diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 450aeaf15f..245b282f2d 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -209,8 +209,8 @@ jobs: id: sonarqube_report_paths shell: bash run: | - 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 + 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@69c1a75940dec6249b86dace6b630d3a2ae9d2a7 # v2.0.1 with: diff --git a/.github/workflows/helm-publish.yml b/.github/workflows/helm-publish.yml new file mode 100644 index 0000000000..8a14ff1a7e --- /dev/null +++ b/.github/workflows/helm-publish.yml @@ -0,0 +1,18 @@ +name: Helm Publish + +on: + pull_request: + types: [ labeled ] + +jobs: + helm_release: + if: ${{ github.event.label.name == 'helm_release' }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Release helm chart + uses: J12934/helm-gh-pages-action@master + with: + charts-folder: charts + deploy-branch: helm-release + access-token: ${{ secrets.HELM_PUSH_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index e562984805..33922321bd 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -684,7 +684,7 @@ jobs: # - run: echo "this exists so we don't have to run anything else if the build is skipped" # if: needs.changes.outputs.src == 'false' || needs.solana-test-image-exists.outputs.exists == 'true' # -# solana-smoke-tests: +# solana-smoke-tests-matrix: # if: ${{ !contains(join(github.event.pull_request.labels.*.name, ' '), 'skip-smoke-tests') }} # environment: integration # permissions: @@ -695,7 +695,7 @@ jobs: # strategy: # matrix: # image: -# - name: "" +# - name: (legacy) # tag-suffix: "" # - name: (plugins) # tag-suffix: -plugins @@ -753,6 +753,26 @@ jobs: # path: /tmp/gotest.log # retention-days: 7 # continue-on-error: true +# +# ### Used to check the required checks box when the matrix completes +# solana-smoke-tests: +# if: always() +# runs-on: ubuntu-latest +# name: Solana Smoke Tests +# needs: [solana-smoke-tests-matrix] +# steps: +# - name: Check smoke test matrix status +# if: needs.solana-smoke-tests-matrix.result != 'success' +# run: exit 1 +# - 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: Solana Smoke Tests +# continue-on-error: true # ### End Solana Section # # ### Start Live Testnet Section @@ -828,7 +848,7 @@ jobs: # # testnet-smoke-tests-notify: # name: Live Testnet Start Slack Thread -# if: ${{ github.event_name == 'schedule' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) && needs.*.result != 'skipped' }} +# if: ${{ always() && needs.testnet-smoke-tests-matrix.result != 'skipped' && needs.testnet-smoke-tests-matrix.result != 'cancelled' }} # environment: integration # outputs: # thread_ts: ${{ steps.slack.outputs.thread_ts }} @@ -880,7 +900,7 @@ jobs: # # testnet-smoke-tests-results: # name: Post Live Testnet Smoke Test Results -# if: ${{ github.event_name == 'schedule' || (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')) && needs.*.result != 'skipped' }} +# if: ${{ always() && needs.testnet-smoke-tests-matrix.result != 'skipped' && needs.testnet-smoke-tests-matrix.result != 'cancelled' }} # environment: integration # permissions: # checks: write diff --git a/.github/workflows/lint-gh-workflows.yml b/.github/workflows/lint-gh-workflows.yml index cc7b44bc28..66c6942060 100644 --- a/.github/workflows/lint-gh-workflows.yml +++ b/.github/workflows/lint-gh-workflows.yml @@ -9,7 +9,7 @@ jobs: - name: Check out Code uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - name: Run actionlint - uses: reviewdog/action-actionlint@67ec075cacebd361442f6e3ef7671f74c6548909 # v1.38.0 + uses: reviewdog/action-actionlint@17ea0452ae2cd009a22ca629732a9ce7f49a55e6 # v1.39.0 - name: Collect Metrics if: always() id: collect-gha-metrics diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6b63f47436..a09f9ce933 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,13 +3,15 @@ name: publish on: push: tags: - - 'v*' + - "v*" branches: - ccip-develop - deployment-test jobs: build-and-publish: + # Do not trigger from versioned tags. + if: ${{ ! startsWith(github.ref, 'refs/tags/v') }} environment: publish permissions: id-token: write @@ -39,21 +41,83 @@ jobs: role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }} aws-region: ${{ secrets.AWS_REGION }} - name: Login to ECR - uses: docker/login-action@42d299face0c5c43a0487c477f595ac9cf22f1a7 #v1.12.0 + uses: docker/login-action@42d299face0c5c43a0487c477f595ac9cf22f1a7 # v1.12.0 with: registry: ${{ secrets.AWS_ECR_REPO_URL }} - # We add SemVer build metadata to indicate the core version in a git tag - # like: v0.2.0-beta.0+core2.0.0 - # The plus "+" sign is invalid for Docker images so we replace it with a - # hyphen "-". We also remove the leading "v" prefix from the tag. + - name: Docker meta + id: docker_meta + uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 # v4.3.0 + with: + images: ${{ secrets.AWS_ECR_REPO_URL }} # list of Docker images to use as base name for tags + tags: | + type=sha,enable={{is_default_branch}} + type=sha,format=long,enable={{is_default_branch}} + - name: Fetch operator-ui + shell: bash + env: + GH_TOKEN: ${{ github.token }} + run: make operator-ui + - name: Build and push + id: docker_build + uses: docker/build-push-action@c56af957549030174b10d6867f20e78cfd7debc5 # v3.2.0 + with: + context: . + push: true + file: ./core/chainlink.Dockerfile + tags: ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} + build-args: | + CHAINLINK_USER=chainlink + build-and-publish-release: + # Trigger only from versioned tags. + if: ${{ startsWith(github.ref, 'refs/tags/v') }} + environment: publish + env: + # Public ECR is only available in us-east-1; not a secret. + AWS_REGION: us-east-1 + AWS_ECR_REPO_PUBLIC_REGISTRY: public.ecr.aws + permissions: + id-token: write + contents: read + runs-on: ubuntu-latest + steps: + - name: Collect Metrics + 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: build-and-publish-release + continue-on-error: true + + - name: Checkout the repo + uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f # v3.4.0 + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@94ab11c41e45d028884a99163086648e898eed25 # v1.6.0 + with: + version: latest + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@67fbcbb121271f7775d2e7715933280b06314838 # v1.7.0 + with: + role-to-assume: ${{ secrets.AWS_OIDC_IAM_ROLE_PROD_PUBLISH_ARN }} + role-duration-seconds: ${{ secrets.AWS_ROLE_DURATION_SECONDS }} + aws-region: ${{ env.AWS_REGION }} + - name: Login to ECR + uses: docker/login-action@42d299face0c5c43a0487c477f595ac9cf22f1a7 # v1.12.0 + with: + registry: ${{ env.AWS_ECR_REPO_PUBLIC_REGISTRY }} + # We use the core SemVer version and then append the the CCIP version in + # a git tag like: v2.5.0-ccip1.1.1 + # We also remove the leading "v" prefix from the tag and convert any "+" + # to "-". - name: Generate Docker image version tag - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') id: generate-docker-image-tag shell: bash run: | # The "#v" removes the "v" prefix from the ref name GITHUB_REF_NAME="${GITHUB_REF_NAME#v}" - # Replace "+" with "-" to make it a valid Docker tag + # Replace any "+" with "-" to make it a valid Docker tag GITHUB_REF_NAME="${GITHUB_REF_NAME//+/-}" OUTPUT="type=raw,value=${GITHUB_REF_NAME},enable=true" echo "tag=${OUTPUT}" | tee -a "${GITHUB_OUTPUT}" @@ -61,17 +125,14 @@ jobs: id: docker_meta uses: docker/metadata-action@507c2f2dc502c992ad446e3d7a5dfbe311567a96 # v4.3.0 with: - images: ${{ secrets.AWS_ECR_REPO_URL }} # list of Docker images to use as base name for tags + images: ${{ env.AWS_ECR_REPO_PUBLIC_REGISTRY }}/w0i8p0z9/chainlink-ccip tags: | - type=sha - type=sha,format=long - type=raw,value=latest,enable={{is_default_branch}} ${{ steps.generate-docker-image-tag.outputs.tag }} - name: Fetch operator-ui shell: bash env: GH_TOKEN: ${{ github.token }} - run: make operator-ui + run: make operator-ui - name: Build and push id: docker_build uses: docker/build-push-action@c56af957549030174b10d6867f20e78cfd7debc5 # v3.2.0 diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 6f8f73961c..d1547e8c53 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -136,17 +136,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@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0 - 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@d2c2b7bdc9012651230b2608a1bcb0c48538b6ec with: diff --git a/.tool-versions b/.tool-versions index 1916a35028..9b2fa11518 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,4 +1,4 @@ -golang 1.20.4 +golang 1.21.1 mockery 2.28.1 nodejs 16.16.0 postgres 13.3 diff --git a/README.md b/README.md index b1e56a7002..f8dd24ffcc 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ regarding Chainlink social accounts, news, and networking. ## Build Chainlink -1. [Install Go 1.20](https://golang.org/doc/install), and add your GOPATH's [bin directory to your PATH](https://golang.org/doc/code.html#GOPATH) +1. [Install Go 1.21.1](https://golang.org/doc/install), and add your GOPATH's [bin directory to your PATH](https://golang.org/doc/code.html#GOPATH) - Example Path for macOS `export PATH=$GOPATH/bin:$PATH` & `export GOPATH=/Users/$USER/go` 2. Install [NodeJS v16](https://nodejs.org/en/download/package-manager/) & [pnpm via npm](https://pnpm.io/installation#using-npm). - It might be easier long term to use [nvm](https://nodejs.org/en/download/package-manager/#nvm) to switch between node versions for different projects. For example, assuming $NODE_VERSION was set to a valid version of NodeJS, you could run: `nvm install $NODE_VERSION && nvm use $NODE_VERSION` diff --git a/VERSION b/VERSION index 9fd00cdd0b..2b1bc23f9c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v2.5.0-ccip1.2.0 +2.6.0-ccip1.2.0 diff --git a/charts/chainlink-cluster/Chart.yaml b/charts/chainlink-cluster/Chart.yaml index 6b64d71871..bfea29c82e 100644 --- a/charts/chainlink-cluster/Chart.yaml +++ b/charts/chainlink-cluster/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 name: chainlink-cluster description: Chainlink nodes cluster -version: 0.1.0 -appVersion: '0.1.0' \ No newline at end of file +version: 0.1.3 +appVersion: '2.6.0' \ No newline at end of file diff --git a/charts/chainlink-cluster/README.md b/charts/chainlink-cluster/README.md index 179e51f2fa..f7d4c45fa5 100644 --- a/charts/chainlink-cluster/README.md +++ b/charts/chainlink-cluster/README.md @@ -1,7 +1,12 @@ # Chainlink cluster Example CL nodes cluster for system level tests -Enter the shell +Install `kubefwd` (no nixpkg for it yet, planned) +``` +brew install txn2/tap/kubefwd +``` + +Enter the shell (from the root project dir) ``` nix develop ``` @@ -20,9 +25,6 @@ export DEVSPACE_IMAGE="${aws_account}.dkr.ecr.us-west-2.amazonaws.com/chainlink- ``` Enter the shell and deploy ``` -nix develop -cd charts/chainlink-cluster - # set your unique namespace if it's a new cluster devspace use namespace cl-cluster devspace deploy @@ -76,11 +78,36 @@ After that all the changes will be synced automatically Check `.profiles` to understand what is uploaded in profiles `runner` and `node` # Helm -If you would like to use `helm` directly, please uncomment data in `values.yaml` -## Install +If you would like to use `helm` directly, please uncomment data in `values-raw-helm.yaml` +## Install from local files ``` helm install -f values-raw-helm.yaml cl-cluster . ``` +Forward all apps (in another terminal) +``` +sudo kubefwd svc +``` +Then you can connect and run your tests + +## Install from release +Add the repository +``` +helm repo add chainlink-cluster https://raw.githubusercontent.com/smartcontractkit/chainlink/helm-release/ +helm repo update +``` +Set default namespace +``` +kubectl create ns cl-cluster +kubectl config set-context --current --namespace cl-cluster +``` + +Install +``` +helm install -f values-raw-helm.yaml cl-cluster chainlink-cluster/chainlink-cluster --version v0.1.2 +``` + +## Create a new release +Bump version in `Chart.yml` add your changes and add `helm_release` label to any PR to trigger a release ## Helm Test ``` diff --git a/charts/chainlink-cluster/devspace.yaml b/charts/chainlink-cluster/devspace.yaml index 63b6f112fe..54b5f9f01e 100644 --- a/charts/chainlink-cluster/devspace.yaml +++ b/charts/chainlink-cluster/devspace.yaml @@ -43,6 +43,7 @@ deployments: image: ${DEVSPACE_IMAGE} stateful: false geth: + version: v1.12.0 wsrpc-port: 8546 httprpc-port: 8544 networkid: 1337 diff --git a/charts/chainlink-cluster/templates/chainlink-deployment.yaml b/charts/chainlink-cluster/templates/chainlink-deployment.yaml index 3ab1edac60..16665916f5 100644 --- a/charts/chainlink-cluster/templates/chainlink-deployment.yaml +++ b/charts/chainlink-cluster/templates/chainlink-deployment.yaml @@ -47,7 +47,7 @@ spec: name: {{ $.Release.Name }}-{{ $cfg.name }}-cm containers: - name: chainlink-db - image: {{ default "postgres" $.Values.db.image }}:{{ default "11.15" $.Values.db.version }} + image: {{ default "postgres:11.15" $.Values.db.image }} command: - docker-entrypoint.sh args: @@ -164,15 +164,15 @@ spec: limits: memory: {{ default "1024Mi" $.Values.chainlink.resources.limits.memory }} cpu: {{ default "500m" $.Values.chainlink.resources.limits.cpu }} - {{- with $.Values.nodeSelector }} {{ else }} {{ end }} +{{- with $.Values.nodeSelector }} nodeSelector: -{{ toYaml . | indent 8 }} + {{ toYaml . | indent 8 }} {{- end }} {{- with $.Values.affinity }} affinity: -{{ toYaml . | indent 8 }} + {{ toYaml . | indent 8 }} {{- end }} {{- with $.Values.tolerations }} tolerations: diff --git a/charts/chainlink-cluster/templates/geth-deployment.yaml b/charts/chainlink-cluster/templates/geth-deployment.yaml index 72c2089210..11fb0cbee2 100644 --- a/charts/chainlink-cluster/templates/geth-deployment.yaml +++ b/charts/chainlink-cluster/templates/geth-deployment.yaml @@ -4,7 +4,6 @@ kind: Deployment metadata: name: geth spec: - replicas: {{ .Values.replicas }} selector: matchLabels: app: geth @@ -102,11 +101,11 @@ spec: {{ end }} {{- with .Values.nodeSelector }} nodeSelector: -{{ toYaml . | indent 8 }} + {{ toYaml . | indent 8 }} {{- end }} {{- with .Values.affinity }} affinity: -{{ toYaml . | indent 8 }} + {{ toYaml . | indent 8 }} {{- end }} {{- with .Values.tolerations }} tolerations: diff --git a/charts/chainlink-cluster/templates/mockserver.yaml b/charts/chainlink-cluster/templates/mockserver.yaml index 998687790b..96f9582435 100755 --- a/charts/chainlink-cluster/templates/mockserver.yaml +++ b/charts/chainlink-cluster/templates/mockserver.yaml @@ -43,19 +43,18 @@ spec: limits: memory: {{ default "1024Mi" $.Values.chainlink.resources.limits.memory }} cpu: {{ default "500m" $.Values.chainlink.resources.limits.cpu }} - {{- with $.Values.nodeSelector }} {{ else }} {{ end }} -{{- with .Values.nodeSelector }} + {{- with .Values.nodeSelector }} nodeSelector: -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.affinity }} + {{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.affinity }} affinity: -{{ toYaml . | indent 8 }} -{{- end }} -{{- with .Values.tolerations }} + {{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} tolerations: -{{ toYaml . | indent 8 }} -{{- end }} - {{ end }} \ No newline at end of file + {{ toYaml . | indent 8 }} + {{- end }} +--- \ No newline at end of file diff --git a/charts/chainlink-cluster/templates/runner-deployment.yaml b/charts/chainlink-cluster/templates/runner-deployment.yaml index 41b24a770f..5d9025b41c 100644 --- a/charts/chainlink-cluster/templates/runner-deployment.yaml +++ b/charts/chainlink-cluster/templates/runner-deployment.yaml @@ -49,9 +49,9 @@ spec: limits: memory: {{ default "1024Mi" $.Values.runner.resources.limits.memory }} cpu: {{ default "500m" $.Values.runner.resources.limits.cpu }} - {{- with $.Values.nodeSelector }} {{ else }} {{ end }} +{{- with $.Values.nodeSelector }} nodeSelector: {{ toYaml . | indent 8 }} {{- end }} diff --git a/charts/chainlink-cluster/values-raw-helm.yaml b/charts/chainlink-cluster/values-raw-helm.yaml index cd1bf8503e..006515f0a3 100644 --- a/charts/chainlink-cluster/values-raw-helm.yaml +++ b/charts/chainlink-cluster/values-raw-helm.yaml @@ -14,16 +14,48 @@ chainlink: p2p_port: 8090 nodes: - name: node-1 + image: "public.ecr.aws/chainlink/chainlink:latest" # override default config per node - #toml: | - # [Log] - # JSONConsole = true - # override image and a tag - # image: public.ecr.aws/chainlink/chainlink - # version: latest + # for example, use OCRv2 P2P setup, the whole config +# toml: | +# RootDir = './clroot' +# [Log] +# JSONConsole = true +# Level = 'debug' +# [WebServer] +# AllowOrigins = '*' +# SecureCookies = false +# SessionTimeout = '999h0m0s' +# [OCR2] +# Enabled = true +# [P2P] +# [P2P.V2] +# Enabled = false +# AnnounceAddresses = [] +# DefaultBootstrappers = [] +# DeltaDial = '15s' +# DeltaReconcile = '1m0s' +# ListenAddresses = [] +# [[EVM]] +# ChainID = '1337' +# MinContractPayment = '0' +# [[EVM.Nodes]] +# Name = 'node-0' +# WSURL = 'ws://geth:8546' +# HTTPURL = 'http://geth:8544' +# [WebServer.TLS] +# HTTPSPort = 0 - name: node-2 - name: node-3 - name: node-4 + resources: + requests: + cpu: 350m + memory: 1024Mi + limits: + cpu: 350m + memory: 1024Mi + # each CL node have a dedicated PostgreSQL 11.15 # use StatefulSet by setting: # @@ -33,24 +65,53 @@ chainlink: # if you are running long tests db: stateful: false + resources: + requests: + cpu: 1 + memory: 1024Mi + limits: + cpu: 1 + memory: 1024Mi # default cluster shipped with latest Geth ( dev mode by default ) geth: + version: v1.12.0 wsrpc-port: 8546 httprpc-port: 8544 networkid: 1337 blocktime: 1 + resources: + requests: + cpu: 1 + memory: 1024Mi + limits: + cpu: 1 + memory: 1024Mi # mockserver is https://www.mock-server.com/where/kubernetes.html # used to stub External Adapters mockserver: port: 1080 + resources: + requests: + cpu: 1 + memory: 1024Mi + limits: + cpu: 1 + memory: 1024Mi runner: stateful: false + resources: + requests: + cpu: 1 + memory: 512Mi + limits: + cpu: 1 + memory: 512Mi # monitoring.coreos.com/v1 PodMonitor for each node prometheusMonitor: false # deployment placement, standard helm stuff -podAnnotations: { } -nodeSelector: { } -tolerations: [ ] -affinity: { } +podAnnotations: +nodeSelector: +tolerations: +affinity: diff --git a/contracts/foundry.toml b/contracts/foundry.toml index 829c07eaa8..5cb35f8cdb 100644 --- a/contracts/foundry.toml +++ b/contracts/foundry.toml @@ -21,7 +21,6 @@ solc_version = '0.8.19' src = 'src/v0.8/ccip' test = 'src/v0.8/ccip/test' optimizer_runs = 26_000 -deny_warnings = true [profile.metatx] solc_version = '0.8.15' diff --git a/contracts/gas-snapshots/ccip.gas-snapshot b/contracts/gas-snapshots/ccip.gas-snapshot index 8b1caf2c28..95f77638e8 100644 --- a/contracts/gas-snapshots/ccip.gas-snapshot +++ b/contracts/gas-snapshots/ccip.gas-snapshot @@ -52,96 +52,97 @@ AggregateTokenLimiter_setAdmin:testOwnerSuccess() (gas: 18631) AggregateTokenLimiter_setRateLimiterConfig:testOnlyOnlyCallableByAdminOrOwnerReverts() (gas: 21552) AggregateTokenLimiter_setRateLimiterConfig:testOwnerSuccess() (gas: 41466) AggregateTokenLimiter_setRateLimiterConfig:testTokenLimitAdminSuccess() (gas: 48072) -BurnMintERC677_burn:testPoolBurnRevertNotHealthyReverts() (gas: 58150) -BurnMintERC677_burn:testPoolBurnSuccess() (gas: 197641) -BurnMintERC677_mint:testPoolMintNotHealthyReverts() (gas: 55384) -BurnMintERC677_mint:testPoolMintSuccess() (gas: 93675) -CCIPClientExample_sanity:testExamples() (gas: 2213780) -CommitStore_constructor:testConstructorSuccess() (gas: 3307574) +BurnMintERC677_burn:testPoolBurnRevertNotHealthyReverts() (gas: 58172) +BurnMintERC677_burn:testPoolBurnSuccess() (gas: 197691) +BurnMintERC677_mint:testPoolMintNotHealthyReverts() (gas: 55341) +BurnMintERC677_mint:testPoolMintSuccess() (gas: 93632) +CCIPClientExample_sanity:testExamples() (gas: 2214087) +CommitStore_constructor:testConstructorSuccess() (gas: 3344466) CommitStore_isUnpausedAndARMHealthy:testARMSuccess() (gas: 71312) -CommitStore_report:testInvalidIntervalMinLargerThanMaxReverts() (gas: 26019) -CommitStore_report:testInvalidIntervalReverts() (gas: 25938) -CommitStore_report:testInvalidRootRevert() (gas: 25226) -CommitStore_report:testOnlyPriceUpdateStaleReportReverts() (gas: 57642) -CommitStore_report:testOnlyPriceUpdatesSuccess() (gas: 52214) -CommitStore_report:testPausedReverts() (gas: 21218) -CommitStore_report:testReportAndPriceUpdateSuccess() (gas: 82755) -CommitStore_report:testReportOnlyRootSuccess_gas() (gas: 53715) -CommitStore_report:testRootAlreadyCommittedReverts() (gas: 60723) -CommitStore_report:testStaleReportWithRootSuccess() (gas: 111235) -CommitStore_report:testUnhealthyReverts() (gas: 44522) -CommitStore_report:testValidPriceUpdateThenStaleReportWithRootSuccess() (gas: 95412) -CommitStore_report:testZeroEpochAndRoundReverts() (gas: 24902) +CommitStore_report:testInvalidIntervalMinLargerThanMaxReverts() (gas: 26312) +CommitStore_report:testInvalidIntervalReverts() (gas: 26231) +CommitStore_report:testInvalidRootRevert() (gas: 25562) +CommitStore_report:testOnlyGasPriceUpdatesSuccess() (gas: 52632) +CommitStore_report:testOnlyPriceUpdateStaleReportReverts() (gas: 58393) +CommitStore_report:testOnlyTokenPriceUpdatesSuccess() (gas: 52675) +CommitStore_report:testPausedReverts() (gas: 21262) +CommitStore_report:testReportAndPriceUpdateSuccess() (gas: 83288) +CommitStore_report:testReportOnlyRootSuccess_gas() (gas: 54050) +CommitStore_report:testRootAlreadyCommittedReverts() (gas: 61380) +CommitStore_report:testStaleReportWithRootSuccess() (gas: 111983) +CommitStore_report:testUnhealthyReverts() (gas: 44567) +CommitStore_report:testValidPriceUpdateThenStaleReportWithRootSuccess() (gas: 96232) +CommitStore_report:testZeroEpochAndRoundReverts() (gas: 25234) CommitStore_resetUnblessedRoots:testOnlyOwnerReverts() (gas: 11290) -CommitStore_resetUnblessedRoots:testResetUnblessedRootsSuccess() (gas: 144194) +CommitStore_resetUnblessedRoots:testResetUnblessedRootsSuccess() (gas: 145219) CommitStore_setDynamicConfig:testInvalidCommitStoreConfigReverts() (gas: 37145) CommitStore_setDynamicConfig:testOnlyOwnerReverts() (gas: 37281) CommitStore_setDynamicConfig:testPriceEpochClearedSuccess() (gas: 124034) CommitStore_setLatestPriceEpochAndRound:testOnlyOwnerReverts() (gas: 10968) CommitStore_setLatestPriceEpochAndRound:testSetLatestPriceEpochAndRoundSuccess() (gas: 13799) CommitStore_setMinSeqNr:testOnlyOwnerReverts() (gas: 10989) -CommitStore_verify:testBlessedSuccess() (gas: 99739) -CommitStore_verify:testNotBlessedSuccess() (gas: 55602) +CommitStore_verify:testBlessedSuccess() (gas: 100081) +CommitStore_verify:testNotBlessedSuccess() (gas: 55944) CommitStore_verify:testPausedReverts() (gas: 18438) CommitStore_verify:testTooManyLeavesReverts() (gas: 36830) DefensiveExampleTest:testHappyPathSuccess() (gas: 174828) DefensiveExampleTest:testRecovery() (gas: 399728) -E2E:testE2E_3MessagesSuccess_gas() (gas: 863423) -EVM2EVMOffRamp__releaseOrMintTokens:testRateLimitErrorsReverts() (gas: 428056) -EVM2EVMOffRamp__releaseOrMintTokens:testTokenHandlingErrorReverts() (gas: 100322) -EVM2EVMOffRamp__releaseOrMintTokens:testUnsupportedTokenReverts() (gas: 18159) -EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokensSuccess() (gas: 139008) -EVM2EVMOffRamp__report:testReportSuccess() (gas: 126666) -EVM2EVMOffRamp__trialExecute:testRateLimitErrorReverts() (gas: 150522) -EVM2EVMOffRamp__trialExecute:testTokenHandlingErrorIsCaughtSuccess() (gas: 179946) -EVM2EVMOffRamp__trialExecute:test_trialExecuteSuccess() (gas: 228022) -EVM2EVMOffRamp_applyPoolUpdates:testApplyPoolUpdatesSuccess() (gas: 2548304) +E2E:testE2E_3MessagesSuccess_gas() (gas: 865196) +EVM2EVMOffRamp__releaseOrMintTokens:testRateLimitErrorsReverts() (gas: 426656) +EVM2EVMOffRamp__releaseOrMintTokens:testTokenHandlingErrorReverts() (gas: 100007) +EVM2EVMOffRamp__releaseOrMintTokens:testUnsupportedTokenReverts() (gas: 18155) +EVM2EVMOffRamp__releaseOrMintTokens:test_releaseOrMintTokensSuccess() (gas: 138996) +EVM2EVMOffRamp__report:testReportSuccess() (gas: 126633) +EVM2EVMOffRamp__trialExecute:testRateLimitErrorSuccess() (gas: 171280) +EVM2EVMOffRamp__trialExecute:testTokenHandlingErrorIsCaughtSuccess() (gas: 179599) +EVM2EVMOffRamp__trialExecute:test_trialExecuteSuccess() (gas: 227978) +EVM2EVMOffRamp_applyPoolUpdates:testApplyPoolUpdatesSuccess() (gas: 2562444) EVM2EVMOffRamp_applyPoolUpdates:testInvalidTokenPoolConfigReverts() (gas: 17359) EVM2EVMOffRamp_applyPoolUpdates:testOnlyCallableByOwnerReverts() (gas: 16000) -EVM2EVMOffRamp_applyPoolUpdates:testPoolAlreadyExistsReverts() (gas: 5153053) -EVM2EVMOffRamp_applyPoolUpdates:testPoolDoesNotExistReverts() (gas: 2512963) -EVM2EVMOffRamp_applyPoolUpdates:testTokenPoolMismatchReverts() (gas: 5155382) +EVM2EVMOffRamp_applyPoolUpdates:testPoolAlreadyExistsReverts() (gas: 5181459) +EVM2EVMOffRamp_applyPoolUpdates:testPoolDoesNotExistReverts() (gas: 2527193) +EVM2EVMOffRamp_applyPoolUpdates:testTokenPoolMismatchReverts() (gas: 5183789) EVM2EVMOffRamp_ccipReceive:testReverts() (gas: 17094) -EVM2EVMOffRamp_constructor:testCommitStoreAlreadyInUseReverts() (gas: 169257) -EVM2EVMOffRamp_constructor:testConstructorSuccess() (gas: 6004286) -EVM2EVMOffRamp_constructor:testTokenConfigMismatchReverts() (gas: 145623) -EVM2EVMOffRamp_constructor:testZeroOnRampAddressReverts() (gas: 2651907) -EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 136534) -EVM2EVMOffRamp_execute:testEmptyReportReverts() (gas: 18990) -EVM2EVMOffRamp_execute:testInvalidMessageIdReverts() (gas: 33939) -EVM2EVMOffRamp_execute:testInvalidSourceChainReverts() (gas: 49122) -EVM2EVMOffRamp_execute:testManualExecutionNotYetEnabledReverts() (gas: 43953) -EVM2EVMOffRamp_execute:testMessageTooLargeReverts() (gas: 149928) -EVM2EVMOffRamp_execute:testPausedReverts() (gas: 74549) -EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 162924) -EVM2EVMOffRamp_execute:testRootNotCommittedReverts() (gas: 38829) -EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 412650) -EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 172174) -EVM2EVMOffRamp_execute:testSingleMessageToNonCCIPReceiverSuccess() (gas: 245912) -EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114026) -EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 314921) -EVM2EVMOffRamp_execute:testSkippedIncorrectNonceSuccess() (gas: 51676) -EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 130151) -EVM2EVMOffRamp_execute:testTokenDataMismatchReverts() (gas: 49524) -EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 430223) -EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 389520) -EVM2EVMOffRamp_execute:testUnexpectedTokenDataReverts() (gas: 32929) -EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 406629) -EVM2EVMOffRamp_execute:testUnsupportedNumberOfTokensReverts() (gas: 61032) -EVM2EVMOffRamp_execute:testUnsupportedTokenReverts() (gas: 129586) +EVM2EVMOffRamp_constructor:testCommitStoreAlreadyInUseReverts() (gas: 169122) +EVM2EVMOffRamp_constructor:testConstructorSuccess() (gas: 5915400) +EVM2EVMOffRamp_constructor:testTokenConfigMismatchReverts() (gas: 145488) +EVM2EVMOffRamp_constructor:testZeroOnRampAddressReverts() (gas: 2665993) +EVM2EVMOffRamp_execute:testAlreadyExecutedReverts() (gas: 136560) +EVM2EVMOffRamp_execute:testEmptyReportReverts() (gas: 18992) +EVM2EVMOffRamp_execute:testInvalidMessageIdReverts() (gas: 33956) +EVM2EVMOffRamp_execute:testInvalidSourceChainReverts() (gas: 49147) +EVM2EVMOffRamp_execute:testManualExecutionNotYetEnabledReverts() (gas: 43970) +EVM2EVMOffRamp_execute:testMessageTooLargeReverts() (gas: 149953) +EVM2EVMOffRamp_execute:testPausedReverts() (gas: 74581) +EVM2EVMOffRamp_execute:testReceiverErrorSuccess() (gas: 162949) +EVM2EVMOffRamp_execute:testRootNotCommittedReverts() (gas: 38846) +EVM2EVMOffRamp_execute:testRouterYULCallReverts() (gas: 412675) +EVM2EVMOffRamp_execute:testSingleMessageNoTokensSuccess() (gas: 172208) +EVM2EVMOffRamp_execute:testSingleMessageToNonCCIPReceiverSuccess() (gas: 245937) +EVM2EVMOffRamp_execute:testSingleMessagesNoTokensSuccess_gas() (gas: 114035) +EVM2EVMOffRamp_execute:testSkippedIncorrectNonceStillExecutesSuccess() (gas: 314917) +EVM2EVMOffRamp_execute:testSkippedIncorrectNonceSuccess() (gas: 51701) +EVM2EVMOffRamp_execute:testStrictUntouchedToSuccessSuccess() (gas: 130176) +EVM2EVMOffRamp_execute:testTokenDataMismatchReverts() (gas: 49541) +EVM2EVMOffRamp_execute:testTwoMessagesWithTokensAndGESuccess() (gas: 430175) +EVM2EVMOffRamp_execute:testTwoMessagesWithTokensSuccess_gas() (gas: 389448) +EVM2EVMOffRamp_execute:testUnexpectedTokenDataReverts() (gas: 32945) +EVM2EVMOffRamp_execute:testUnhealthyReverts() (gas: 406605) +EVM2EVMOffRamp_execute:testUnsupportedNumberOfTokensReverts() (gas: 61057) +EVM2EVMOffRamp_execute:testUnsupportedTokenReverts() (gas: 129634) EVM2EVMOffRamp_executeSingleMessage:testMessageSenderReverts() (gas: 20494) EVM2EVMOffRamp_executeSingleMessage:testNoTokensSuccess() (gas: 47668) EVM2EVMOffRamp_executeSingleMessage:testNonContractSuccess() (gas: 20042) -EVM2EVMOffRamp_executeSingleMessage:testNonContractWithTokensSuccess() (gas: 196939) -EVM2EVMOffRamp_executeSingleMessage:testTokenHandlingErrorReverts() (gas: 136903) -EVM2EVMOffRamp_executeSingleMessage:testTokensSuccess() (gas: 225488) +EVM2EVMOffRamp_executeSingleMessage:testNonContractWithTokensSuccess() (gas: 196895) +EVM2EVMOffRamp_executeSingleMessage:testTokenHandlingErrorReverts() (gas: 136556) +EVM2EVMOffRamp_executeSingleMessage:testTokensSuccess() (gas: 225444) EVM2EVMOffRamp_executeSingleMessage:testZeroGasDONExecutionReverts() (gas: 48191) EVM2EVMOffRamp_execute_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 230624) EVM2EVMOffRamp_execute_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 277815) EVM2EVMOffRamp_execute_upgrade:testV2OffRampNonceSkipsIfMsgInFlightSuccess() (gas: 259301) EVM2EVMOffRamp_execute_upgrade:testV2SenderNoncesReadsPreviousRampSuccess() (gas: 223057) EVM2EVMOffRamp_execute_upgrade:testV2Success() (gas: 130696) -EVM2EVMOffRamp_getDestinationToken:testGetDestinationTokenSuccess() (gas: 32662) +EVM2EVMOffRamp_getDestinationToken:testGetDestinationTokenSuccess() (gas: 32616) EVM2EVMOffRamp_getDestinationToken:testUnsupportedTokenReverts() (gas: 13728) EVM2EVMOffRamp_getDestinationTokens:testGetDestinationTokensSuccess() (gas: 26043) EVM2EVMOffRamp_getExecutionState:testFillExecutionStateSuccess() (gas: 3047472) @@ -152,24 +153,24 @@ EVM2EVMOffRamp_manuallyExecute:testManualExecGasLimitMismatchReverts() (gas: 434 EVM2EVMOffRamp_manuallyExecute:testManualExecInvalidGasLimitReverts() (gas: 25940) EVM2EVMOffRamp_manuallyExecute:testManualExecSuccess() (gas: 188359) EVM2EVMOffRamp_manuallyExecute:testManualExecWithGasOverrideSuccess() (gas: 188939) -EVM2EVMOffRamp_manuallyExecute:testReentrancyManualExecuteFAILS() (gas: 1890571) +EVM2EVMOffRamp_manuallyExecute:testReentrancyManualExecuteFAILS() (gas: 1890548) EVM2EVMOffRamp_metadataHash:testMetadataHashSuccess() (gas: 6074) EVM2EVMOffRamp_setDynamicConfig:testNonOwnerReverts() (gas: 44264) EVM2EVMOffRamp_setDynamicConfig:testRouterZeroAddressReverts() (gas: 38118) EVM2EVMOffRamp_setDynamicConfig:testSetDynamicConfigSuccess() (gas: 139455) -EVM2EVMOnRamp_applyPoolUpdates:testAddTokenPoolMismatchReverts() (gas: 275660) -EVM2EVMOnRamp_applyPoolUpdates:testApplyPoolUpdatesSuccess() (gas: 301257) -EVM2EVMOnRamp_applyPoolUpdates:testAtomicPoolReplacementSuccess() (gas: 631241) -EVM2EVMOnRamp_applyPoolUpdates:testInvalidTokenPoolConfigReverts() (gas: 18495) -EVM2EVMOnRamp_applyPoolUpdates:testOnlyCallableByOwnerReverts() (gas: 23154) -EVM2EVMOnRamp_applyPoolUpdates:testPoolAlreadyExistsReverts() (gas: 351576) -EVM2EVMOnRamp_applyPoolUpdates:testPoolDoesNotExistReverts() (gas: 277882) -EVM2EVMOnRamp_applyPoolUpdates:testRemoveTokenPoolMismatchReverts() (gas: 616024) -EVM2EVMOnRamp_constructor:testConstructorSuccess() (gas: 5774116) +EVM2EVMOnRamp_applyPoolUpdates:testAddTokenPoolMismatchReverts() (gas: 275638) +EVM2EVMOnRamp_applyPoolUpdates:testApplyPoolUpdatesSuccess() (gas: 301347) +EVM2EVMOnRamp_applyPoolUpdates:testAtomicPoolReplacementSuccess() (gas: 631331) +EVM2EVMOnRamp_applyPoolUpdates:testInvalidTokenPoolConfigReverts() (gas: 18451) +EVM2EVMOnRamp_applyPoolUpdates:testOnlyCallableByOwnerReverts() (gas: 23110) +EVM2EVMOnRamp_applyPoolUpdates:testPoolAlreadyExistsReverts() (gas: 351554) +EVM2EVMOnRamp_applyPoolUpdates:testPoolDoesNotExistReverts() (gas: 277860) +EVM2EVMOnRamp_applyPoolUpdates:testRemoveTokenPoolMismatchReverts() (gas: 615980) +EVM2EVMOnRamp_constructor:testConstructorSuccess() (gas: 5731888) EVM2EVMOnRamp_forwardFromRouter:testCannotSendZeroTokensReverts() (gas: 31534) -EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccess() (gas: 126628) -EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessCustomExtraArgs() (gas: 126940) -EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessLegacyExtraArgs() (gas: 137359) +EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccess() (gas: 126626) +EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessCustomExtraArgs() (gas: 126938) +EVM2EVMOnRamp_forwardFromRouter:testForwardFromRouterSuccessLegacyExtraArgs() (gas: 137357) EVM2EVMOnRamp_forwardFromRouter:testInvalidAddressEncodePackedReverts() (gas: 23964) EVM2EVMOnRamp_forwardFromRouter:testInvalidAddressReverts() (gas: 24263) EVM2EVMOnRamp_forwardFromRouter:testInvalidExtraArgsTagReverts() (gas: 23265) @@ -178,86 +179,86 @@ EVM2EVMOnRamp_forwardFromRouter:testMaxFeeBalanceReachedReverts() (gas: 32218) EVM2EVMOnRamp_forwardFromRouter:testMessageGasLimitTooHighReverts() (gas: 26907) EVM2EVMOnRamp_forwardFromRouter:testMessageTooLargeReverts() (gas: 105488) EVM2EVMOnRamp_forwardFromRouter:testOriginalSenderReverts() (gas: 20165) -EVM2EVMOnRamp_forwardFromRouter:testPausedReverts() (gas: 49568) +EVM2EVMOnRamp_forwardFromRouter:testPausedReverts() (gas: 49635) EVM2EVMOnRamp_forwardFromRouter:testPermissionsReverts() (gas: 26836) EVM2EVMOnRamp_forwardFromRouter:testPriceNotFoundForTokenReverts() (gas: 34938) -EVM2EVMOnRamp_forwardFromRouter:testShouldIncrementSeqNumAndNonceSuccess() (gas: 168385) -EVM2EVMOnRamp_forwardFromRouter:testShouldStoreLinkFees() (gas: 104372) -EVM2EVMOnRamp_forwardFromRouter:testShouldStoreNonLinkFees() (gas: 123580) +EVM2EVMOnRamp_forwardFromRouter:testShouldIncrementSeqNumAndNonceSuccess() (gas: 168379) +EVM2EVMOnRamp_forwardFromRouter:testShouldStoreLinkFees() (gas: 104350) +EVM2EVMOnRamp_forwardFromRouter:testShouldStoreNonLinkFees() (gas: 123558) EVM2EVMOnRamp_forwardFromRouter:testTooManyTokensReverts() (gas: 28119) EVM2EVMOnRamp_forwardFromRouter:testUnhealthyReverts() (gas: 42966) -EVM2EVMOnRamp_forwardFromRouter:testUnsupportedTokenReverts() (gas: 108831) +EVM2EVMOnRamp_forwardFromRouter:testUnsupportedTokenReverts() (gas: 109084) EVM2EVMOnRamp_forwardFromRouter:testZeroAddressReceiverReverts() (gas: 154448) -EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 141893) -EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 184775) +EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceNewSenderStartsAtZeroSuccess() (gas: 141889) +EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2NonceStartsAtV1NonceSuccess() (gas: 184767) EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2SenderNoncesReadsPreviousRampSuccess() (gas: 112643) -EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2Success() (gas: 92203) -EVM2EVMOnRamp_getDataAvailabilityCostUSD:testEmptyMessageCalculatesDataAvailabilityCostSuccess() (gas: 15075) -EVM2EVMOnRamp_getDataAvailabilityCostUSD:testSimpleMessageCalculatesDataAvailabilityCostSuccess() (gas: 15388) -EVM2EVMOnRamp_getExpectedNextSequenceNumber:testGetExpectedNextSequenceNumberSuccess() (gas: 7860) -EVM2EVMOnRamp_getFee:testEmptyMessageSuccess() (gas: 68388) -EVM2EVMOnRamp_getFee:testHighGasMessageSuccess() (gas: 224358) -EVM2EVMOnRamp_getFee:testMessageGasLimitTooHighReverts() (gas: 16453) -EVM2EVMOnRamp_getFee:testMessageTooLargeReverts() (gas: 94976) -EVM2EVMOnRamp_getFee:testMessageWithDataAndTokenTransferSuccess() (gas: 129846) -EVM2EVMOnRamp_getFee:testNotAFeeTokenReverts() (gas: 21715) -EVM2EVMOnRamp_getFee:testSingleTokenMessageSuccess() (gas: 99608) -EVM2EVMOnRamp_getFee:testTooManyTokensReverts() (gas: 19644) -EVM2EVMOnRamp_getFee:testZeroDataAvailabilityMultiplierSuccess() (gas: 54013) -EVM2EVMOnRamp_getSupportedTokens:testGetSupportedTokensSuccess() (gas: 51549) -EVM2EVMOnRamp_getTokenPool:testGetTokenPoolSuccess() (gas: 40912) -EVM2EVMOnRamp_getTokenTransferCost:testCustomTokenBpsFeeSuccess() (gas: 40105) -EVM2EVMOnRamp_getTokenTransferCost:testFeeTokenBpsFeeSuccess() (gas: 30352) -EVM2EVMOnRamp_getTokenTransferCost:testLargeTokenTransferChargesMaxFeeAndGasSuccess() (gas: 25697) -EVM2EVMOnRamp_getTokenTransferCost:testMixedTokenTransferFeeSuccess() (gas: 109527) -EVM2EVMOnRamp_getTokenTransferCost:testNoTokenTransferChargesMinFeeSuccess() (gas: 17121) -EVM2EVMOnRamp_getTokenTransferCost:testSmallTokenTransferChargesMinFeeAndGasSuccess() (gas: 25507) -EVM2EVMOnRamp_getTokenTransferCost:testUnsupportedTokenReverts() (gas: 25338) -EVM2EVMOnRamp_getTokenTransferCost:testValidatedPriceStalenessReverts() (gas: 42529) -EVM2EVMOnRamp_getTokenTransferCost:testWETHTokenBpsFeeSuccess() (gas: 36256) -EVM2EVMOnRamp_getTokenTransferCost:testZeroAmountTokenTransferChargesMinFeeAndAgasSuccess() (gas: 25527) -EVM2EVMOnRamp_getTokenTransferCost:testZeroFeeConfigChargesMinFeeSuccess() (gas: 29472) -EVM2EVMOnRamp_linkAvailableForPayment:testInsufficientLinkBalanceSuccess() (gas: 37935) -EVM2EVMOnRamp_linkAvailableForPayment:testLinkAvailableForPaymentSuccess() (gas: 138268) -EVM2EVMOnRamp_payNops:testAdminPayNopsSuccess() (gas: 146336) -EVM2EVMOnRamp_payNops:testInsufficientBalanceReverts() (gas: 32152) -EVM2EVMOnRamp_payNops:testNoFeesToPayReverts() (gas: 131481) -EVM2EVMOnRamp_payNops:testNoNopsToPayReverts() (gas: 136500) -EVM2EVMOnRamp_payNops:testNopPayNopsSuccess() (gas: 149589) -EVM2EVMOnRamp_payNops:testOwnerPayNopsSuccess() (gas: 144225) -EVM2EVMOnRamp_payNops:testPayNopsSuccessAfterSetNops() (gas: 299354) -EVM2EVMOnRamp_payNops:testWrongPermissionsReverts() (gas: 19467) -EVM2EVMOnRamp_setDynamicConfig:testSetConfigInvalidConfigReverts() (gas: 37031) -EVM2EVMOnRamp_setDynamicConfig:testSetConfigOnlyOwnerReverts() (gas: 25795) -EVM2EVMOnRamp_setDynamicConfig:testSetDynamicConfigSuccess() (gas: 44343) -EVM2EVMOnRamp_setFeeTokenConfig:testOnlyCallableByOwnerOrAdminReverts() (gas: 17677) -EVM2EVMOnRamp_setFeeTokenConfig:testSetFeeTokenConfigByAdminSuccess() (gas: 20586) -EVM2EVMOnRamp_setFeeTokenConfig:testSetFeeTokenConfigSuccess() (gas: 13950) -EVM2EVMOnRamp_setNops:testAdminCanSetNopsSuccess() (gas: 65220) -EVM2EVMOnRamp_setNops:testIncludesPaymentSuccess() (gas: 434710) -EVM2EVMOnRamp_setNops:testLinkTokenCannotBeNopReverts() (gas: 57250) -EVM2EVMOnRamp_setNops:testNonOwnerOrAdminReverts() (gas: 18777) -EVM2EVMOnRamp_setNops:testNotEnoughFundsForPayoutReverts() (gas: 85735) -EVM2EVMOnRamp_setNops:testSetNopsRemovesOldNopsCompletelySuccess() (gas: 63408) -EVM2EVMOnRamp_setNops:testSetNopsSuccess() (gas: 170843) -EVM2EVMOnRamp_setNops:testTooManyNopsReverts() (gas: 190362) -EVM2EVMOnRamp_setNops:testZeroAddressCannotBeNopReverts() (gas: 53555) -EVM2EVMOnRamp_setTokenTransferFeeConfig:testOnlyCallableByOwnerOrAdminReverts() (gas: 17738) -EVM2EVMOnRamp_setTokenTransferFeeConfig:testSetFeeTokenConfigByAdminSuccess() (gas: 20647) -EVM2EVMOnRamp_setTokenTransferFeeConfig:testSetFeeTokenConfigSuccess() (gas: 50282) -EVM2EVMOnRamp_withdrawNonLinkFees:testInvalidTokenReverts() (gas: 15094) -EVM2EVMOnRamp_withdrawNonLinkFees:testLinkBalanceNotSettledReverts() (gas: 84238) -EVM2EVMOnRamp_withdrawNonLinkFees:testNonOwnerOrAdminReverts() (gas: 19453) -EVM2EVMOnRamp_withdrawNonLinkFees:testSettlingBalanceSuccess() (gas: 244596) -EVM2EVMOnRamp_withdrawNonLinkFees:testWithdrawNonLinkFeesSuccess() (gas: 50104) -EVM2EVMOnRamp_withdrawNonLinkFees:testWithdrawToZeroAddressReverts() (gas: 12913) -LockReleaseTokenPool_addLiquidity:testLiquidityNotAcceptedReverts() (gas: 2509153) -LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquiditySuccess() (gas: 2509647) +EVM2EVMOnRamp_forwardFromRouter_upgrade:testV2Success() (gas: 92199) +EVM2EVMOnRamp_getDataAvailabilityCostUSD:testEmptyMessageCalculatesDataAvailabilityCostSuccess() (gas: 15031) +EVM2EVMOnRamp_getDataAvailabilityCostUSD:testSimpleMessageCalculatesDataAvailabilityCostSuccess() (gas: 15344) +EVM2EVMOnRamp_getExpectedNextSequenceNumber:testGetExpectedNextSequenceNumberSuccess() (gas: 7838) +EVM2EVMOnRamp_getFee:testEmptyMessageSuccess() (gas: 67455) +EVM2EVMOnRamp_getFee:testHighGasMessageSuccess() (gas: 223338) +EVM2EVMOnRamp_getFee:testMessageGasLimitTooHighReverts() (gas: 16431) +EVM2EVMOnRamp_getFee:testMessageTooLargeReverts() (gas: 94954) +EVM2EVMOnRamp_getFee:testMessageWithDataAndTokenTransferSuccess() (gas: 131937) +EVM2EVMOnRamp_getFee:testNotAFeeTokenReverts() (gas: 21629) +EVM2EVMOnRamp_getFee:testSingleTokenMessageSuccess() (gas: 98812) +EVM2EVMOnRamp_getFee:testTooManyTokensReverts() (gas: 19622) +EVM2EVMOnRamp_getFee:testZeroDataAvailabilityMultiplierSuccess() (gas: 53614) +EVM2EVMOnRamp_getSupportedTokens:testGetSupportedTokensSuccess() (gas: 51483) +EVM2EVMOnRamp_getTokenPool:testGetTokenPoolSuccess() (gas: 41113) +EVM2EVMOnRamp_getTokenTransferCost:testCustomTokenBpsFeeSuccess() (gas: 35387) +EVM2EVMOnRamp_getTokenTransferCost:testFeeTokenBpsFeeSuccess() (gas: 25716) +EVM2EVMOnRamp_getTokenTransferCost:testLargeTokenTransferChargesMaxFeeAndGasSuccess() (gas: 21040) +EVM2EVMOnRamp_getTokenTransferCost:testMixedTokenTransferFeeSuccess() (gas: 104565) +EVM2EVMOnRamp_getTokenTransferCost:testNoTokenTransferChargesZeroFeeSuccess() (gas: 11695) +EVM2EVMOnRamp_getTokenTransferCost:testSmallTokenTransferChargesMinFeeAndGasSuccess() (gas: 20850) +EVM2EVMOnRamp_getTokenTransferCost:testUnsupportedTokenReverts() (gas: 20270) +EVM2EVMOnRamp_getTokenTransferCost:testValidatedPriceStalenessReverts() (gas: 37384) +EVM2EVMOnRamp_getTokenTransferCost:testWETHTokenBpsFeeSuccess() (gas: 31606) +EVM2EVMOnRamp_getTokenTransferCost:testZeroAmountTokenTransferChargesMinFeeAndAgasSuccess() (gas: 20870) +EVM2EVMOnRamp_getTokenTransferCost:testZeroFeeConfigChargesMinFeeSuccess() (gas: 30261) +EVM2EVMOnRamp_linkAvailableForPayment:testInsufficientLinkBalanceSuccess() (gas: 37891) +EVM2EVMOnRamp_linkAvailableForPayment:testLinkAvailableForPaymentSuccess() (gas: 138180) +EVM2EVMOnRamp_payNops:testAdminPayNopsSuccess() (gas: 146292) +EVM2EVMOnRamp_payNops:testInsufficientBalanceReverts() (gas: 32130) +EVM2EVMOnRamp_payNops:testNoFeesToPayReverts() (gas: 131437) +EVM2EVMOnRamp_payNops:testNoNopsToPayReverts() (gas: 136517) +EVM2EVMOnRamp_payNops:testNopPayNopsSuccess() (gas: 149545) +EVM2EVMOnRamp_payNops:testOwnerPayNopsSuccess() (gas: 144181) +EVM2EVMOnRamp_payNops:testPayNopsSuccessAfterSetNops() (gas: 299353) +EVM2EVMOnRamp_payNops:testWrongPermissionsReverts() (gas: 19445) +EVM2EVMOnRamp_setDynamicConfig:testSetConfigInvalidConfigReverts() (gas: 37165) +EVM2EVMOnRamp_setDynamicConfig:testSetConfigOnlyOwnerReverts() (gas: 25929) +EVM2EVMOnRamp_setDynamicConfig:testSetDynamicConfigSuccess() (gas: 44388) +EVM2EVMOnRamp_setFeeTokenConfig:testOnlyCallableByOwnerOrAdminReverts() (gas: 17697) +EVM2EVMOnRamp_setFeeTokenConfig:testSetFeeTokenConfigByAdminSuccess() (gas: 20606) +EVM2EVMOnRamp_setFeeTokenConfig:testSetFeeTokenConfigSuccess() (gas: 13970) +EVM2EVMOnRamp_setNops:testAdminCanSetNopsSuccess() (gas: 65255) +EVM2EVMOnRamp_setNops:testIncludesPaymentSuccess() (gas: 434753) +EVM2EVMOnRamp_setNops:testLinkTokenCannotBeNopReverts() (gas: 57284) +EVM2EVMOnRamp_setNops:testNonOwnerOrAdminReverts() (gas: 18820) +EVM2EVMOnRamp_setNops:testNotEnoughFundsForPayoutReverts() (gas: 85778) +EVM2EVMOnRamp_setNops:testSetNopsRemovesOldNopsCompletelySuccess() (gas: 63424) +EVM2EVMOnRamp_setNops:testSetNopsSuccess() (gas: 170886) +EVM2EVMOnRamp_setNops:testTooManyNopsReverts() (gas: 190405) +EVM2EVMOnRamp_setNops:testZeroAddressCannotBeNopReverts() (gas: 53589) +EVM2EVMOnRamp_setTokenTransferFeeConfig:testOnlyCallableByOwnerOrAdminReverts() (gas: 17677) +EVM2EVMOnRamp_setTokenTransferFeeConfig:testSetFeeTokenConfigByAdminSuccess() (gas: 20586) +EVM2EVMOnRamp_setTokenTransferFeeConfig:testSetTokenTransferFeeSuccess() (gas: 54678) +EVM2EVMOnRamp_withdrawNonLinkFees:testInvalidTokenReverts() (gas: 15072) +EVM2EVMOnRamp_withdrawNonLinkFees:testLinkBalanceNotSettledReverts() (gas: 84216) +EVM2EVMOnRamp_withdrawNonLinkFees:testNonOwnerOrAdminReverts() (gas: 19431) +EVM2EVMOnRamp_withdrawNonLinkFees:testSettlingBalanceSuccess() (gas: 244561) +EVM2EVMOnRamp_withdrawNonLinkFees:testWithdrawNonLinkFeesSuccess() (gas: 50082) +EVM2EVMOnRamp_withdrawNonLinkFees:testWithdrawToZeroAddressReverts() (gas: 12891) +LockReleaseTokenPool_addLiquidity:testLiquidityNotAcceptedReverts() (gas: 2523406) +LockReleaseTokenPool_canAcceptLiquidity:test_CanAcceptLiquiditySuccess() (gas: 2523878) LockReleaseTokenPool_lockOrBurn:testLockOrBurnWithAllowListReverts() (gas: 21718) LockReleaseTokenPool_lockOrBurn:testLockOrBurnWithAllowListSuccess() (gas: 60504) LockReleaseTokenPool_lockOrBurn:testPoolBurnRevertNotHealthyReverts() (gas: 64707) -LockReleaseTokenPool_releaseOrMint:testPoolMintNotHealthyReverts() (gas: 57674) -LockReleaseTokenPool_removeLiquidity:testInsufficientLiquidityReverts() (gas: 83061) +LockReleaseTokenPool_releaseOrMint:testPoolMintNotHealthyReverts() (gas: 57696) +LockReleaseTokenPool_removeLiquidity:testInsufficientLiquidityReverts() (gas: 83083) LockReleaseTokenPool_supportsInterface:testSupportsInterfaceSuccess() (gas: 8326) MerkleMultiProofTest:testCVE_2023_34459() (gas: 5458) MerkleMultiProofTest:testEmptyLeafReverts() (gas: 3575) @@ -289,31 +290,33 @@ OCR2Base_transmit:testTransmit2SignersSuccess_gas() (gas: 51741) OCR2Base_transmit:testUnAuthorizedTransmitterReverts() (gas: 23441) OCR2Base_transmit:testUnauthorizedSignerReverts() (gas: 43661) OCR2Base_transmit:testWrongNumberOfSignaturesReverts() (gas: 20507) -OnRampTokenPoolReentrancy:testSuccess() (gas: 332065) -PingPong_ccipReceive:testCcipReceiveSuccess() (gas: 146097) +OnRampTokenPoolReentrancy:testSuccess() (gas: 332145) +PingPong_ccipReceive:testCcipReceiveSuccess() (gas: 146017) PingPong_plumbing:testPausingSuccess() (gas: 14471) -PingPong_startPingPong:testStartPingPongSuccess() (gas: 171175) -PriceRegistry_applyFeeTokensUpdates:testApplyFeeTokensUpdatesSuccess() (gas: 77674) -PriceRegistry_applyFeeTokensUpdates:testOnlyCallableByOwnerReverts() (gas: 16598) -PriceRegistry_applyPriceUpdatersUpdates:testApplyPriceUpdaterUpdatesSuccess() (gas: 80774) -PriceRegistry_applyPriceUpdatersUpdates:testOnlyCallableByOwnerReverts() (gas: 16576) +PingPong_startPingPong:testStartPingPongSuccess() (gas: 171015) +PriceRegistry_applyFeeTokensUpdates:testApplyFeeTokensUpdatesSuccess() (gas: 77463) +PriceRegistry_applyFeeTokensUpdates:testOnlyCallableByOwnerReverts() (gas: 16532) +PriceRegistry_applyPriceUpdatersUpdates:testApplyPriceUpdaterUpdatesSuccess() (gas: 80844) +PriceRegistry_applyPriceUpdatersUpdates:testOnlyCallableByOwnerReverts() (gas: 16598) PriceRegistry_constructor:testInvalidStalenessThresholdReverts() (gas: 66156) -PriceRegistry_constructor:testSetupSuccess() (gas: 1658494) -PriceRegistry_convertTokenAmount:testConvertTokenAmountSuccess() (gas: 60190) +PriceRegistry_constructor:testSetupSuccess() (gas: 1658294) +PriceRegistry_convertTokenAmount:testConvertTokenAmountSuccess() (gas: 65026) PriceRegistry_convertTokenAmount:testLinkTokenNotSupportedReverts() (gas: 22707) -PriceRegistry_convertTokenAmount:testStaleFeeTokenReverts() (gas: 31634) -PriceRegistry_convertTokenAmount:testStaleLinkTokenReverts() (gas: 31104) -PriceRegistry_getTokenAndGasPrices:testGetFeeTokenAndGasPricesSuccess() (gas: 59721) +PriceRegistry_convertTokenAmount:testStaleFeeTokenReverts() (gas: 31901) +PriceRegistry_convertTokenAmount:testStaleLinkTokenReverts() (gas: 31371) +PriceRegistry_getTokenAndGasPrices:testGetFeeTokenAndGasPricesSuccess() (gas: 64650) PriceRegistry_getTokenAndGasPrices:testStaleGasPriceReverts() (gas: 16688) -PriceRegistry_getTokenAndGasPrices:testStaleTokenPriceReverts() (gas: 28960) +PriceRegistry_getTokenAndGasPrices:testStaleTokenPriceReverts() (gas: 29702) PriceRegistry_getTokenAndGasPrices:testUnsupportedChainReverts() (gas: 16030) -PriceRegistry_getTokenAndGasPrices:testZeroGasPriceSuccess() (gas: 39513) -PriceRegistry_getTokenPrices:testGetTokenPricesSuccess() (gas: 68805) -PriceRegistry_getValidatedTokenPrice:testGetValidatedTokenPriceSuccess() (gas: 50773) -PriceRegistry_getValidatedTokenPrice:testStaleFeeTokenReverts() (gas: 16963) -PriceRegistry_getValidatedTokenPrice:testTokenNotSupportedReverts() (gas: 11380) -PriceRegistry_updatePrices:testOnlyCallableByUpdaterOrOwnerReverts() (gas: 41709) -PriceRegistry_updatePrices:testUpdatePricesSuccess() (gas: 66451) +PriceRegistry_getTokenAndGasPrices:testZeroGasPriceSuccess() (gas: 40311) +PriceRegistry_getTokenPrices:testGetTokenPricesSuccess() (gas: 73698) +PriceRegistry_getValidatedTokenPrice:testGetValidatedTokenPriceSuccess() (gas: 55577) +PriceRegistry_getValidatedTokenPrice:testStaleFeeTokenReverts() (gas: 16896) +PriceRegistry_getValidatedTokenPrice:testTokenNotSupportedReverts() (gas: 11313) +PriceRegistry_updatePrices:testOnlyCallableByUpdaterOrOwnerReverts() (gas: 18174) +PriceRegistry_updatePrices:testOnlyGasPriceSuccess() (gas: 23032) +PriceRegistry_updatePrices:testOnlyTokenPriceSuccess() (gas: 27699) +PriceRegistry_updatePrices:testUpdateMultiplePricesSuccess() (gas: 142171) RateLimiter_constructor:testConstructorSuccess() (gas: 15362) RateLimiter_consume:testAggregateValueMaxCapacityExceededReverts() (gas: 15669) RateLimiter_consume:testAggregateValueRateLimitReachedReverts() (gas: 21950) @@ -332,25 +335,25 @@ Router_applyRampUpdates:testOffRampDisable() (gas: 192139) Router_applyRampUpdates:testOffRampMismatchReverts() (gas: 108518) Router_applyRampUpdates:testOnRampDisable() (gas: 52147) Router_applyRampUpdates:testOnlyOwnerReverts() (gas: 12224) -Router_ccipSend:testCCIPSendLinkFeeNoTokenSuccess_gas() (gas: 110238) -Router_ccipSend:testCCIPSendLinkFeeOneTokenSuccess_gas() (gas: 188316) -Router_ccipSend:testCCIPSendNativeFeeNoTokenSuccess_gas() (gas: 122289) -Router_ccipSend:testCCIPSendNativeFeeOneTokenSuccess_gas() (gas: 200368) -Router_ccipSend:testFeeTokenAmountTooLowReverts() (gas: 61367) +Router_ccipSend:testCCIPSendLinkFeeNoTokenSuccess_gas() (gas: 110158) +Router_ccipSend:testCCIPSendLinkFeeOneTokenSuccess_gas() (gas: 188556) +Router_ccipSend:testCCIPSendNativeFeeNoTokenSuccess_gas() (gas: 122209) +Router_ccipSend:testCCIPSendNativeFeeOneTokenSuccess_gas() (gas: 200608) +Router_ccipSend:testFeeTokenAmountTooLowReverts() (gas: 61287) Router_ccipSend:testInvalidMsgValue() (gas: 31860) -Router_ccipSend:testNativeFeeTokenInsufficientValue() (gas: 64237) -Router_ccipSend:testNativeFeeTokenOverpaySuccess() (gas: 161923) -Router_ccipSend:testNativeFeeTokenSuccess() (gas: 161264) -Router_ccipSend:testNativeFeeTokenZeroValue() (gas: 51217) -Router_ccipSend:testNonLinkFeeTokenSuccess() (gas: 233465) +Router_ccipSend:testNativeFeeTokenInsufficientValue() (gas: 63758) +Router_ccipSend:testNativeFeeTokenOverpaySuccess() (gas: 161763) +Router_ccipSend:testNativeFeeTokenSuccess() (gas: 161104) +Router_ccipSend:testNativeFeeTokenZeroValue() (gas: 51137) +Router_ccipSend:testNonLinkFeeTokenSuccess() (gas: 232091) Router_ccipSend:testUnsupportedDestinationChainReverts() (gas: 24624) Router_ccipSend:testWhenNotHealthyReverts() (gas: 44650) -Router_ccipSend:testWrappedNativeFeeTokenSuccess() (gas: 163363) -Router_ccipSend:testZeroFeeAndGasPriceSuccess() (gas: 229200) +Router_ccipSend:testWrappedNativeFeeTokenSuccess() (gas: 163203) +Router_ccipSend:testZeroFeeAndGasPriceSuccess() (gas: 228894) Router_constructor:testConstructorSuccess() (gas: 9929) -Router_getFee:testGetFeeSupportedChainSuccess() (gas: 38866) +Router_getFee:testGetFeeSupportedChainSuccess() (gas: 38786) Router_getFee:testUnsupportedDestinationChainReverts() (gas: 17079) -Router_getSupportedTokens:testGetSupportedTokensSuccess() (gas: 33435) +Router_getSupportedTokens:testGetSupportedTokensSuccess() (gas: 33413) Router_getSupportedTokens:testUnknownChainSuccess() (gas: 8542) Router_recoverTokens:testRecoverTokensInvalidRecipientReverts() (gas: 11211) Router_recoverTokens:testRecoverTokensNoFundsReverts() (gas: 17675) @@ -363,9 +366,9 @@ Router_routeMessage:testManualExecSuccess() (gas: 31211) Router_routeMessage:testOnlyOffRampReverts() (gas: 22025) Router_routeMessage:testWhenNotHealthyReverts() (gas: 45570) Router_setWrappedNative:testOnlyOwnerReverts() (gas: 10976) -ThirdPartyBurnMintTokenPool_applyRampUpdates:testInvalidOffRampReverts() (gas: 23375) -ThirdPartyBurnMintTokenPool_lockOrBurn:testLockOrBurnWithAllowListReverts() (gas: 21732) -ThirdPartyBurnMintTokenPool_lockOrBurn:testLockOrBurnWithAllowListSuccess() (gas: 99869) +ThirdPartyBurnMintTokenPool_applyRampUpdates:testInvalidOffRampReverts() (gas: 23397) +ThirdPartyBurnMintTokenPool_lockOrBurn:testLockOrBurnWithAllowListReverts() (gas: 21754) +ThirdPartyBurnMintTokenPool_lockOrBurn:testLockOrBurnWithAllowListSuccess() (gas: 99993) TokenPoolWithAllowList_applyAllowListUpdates:testOnlyOwnerReverts() (gas: 12072) TokenPoolWithAllowList_applyAllowListUpdates:testSetAllowListSkipsZeroSuccess() (gas: 20409) TokenPoolWithAllowList_applyAllowListUpdates:testSetAllowListSuccess() (gas: 175191) @@ -379,28 +382,28 @@ TokenPool_setOffRampRateLimiterConfig:testOnlyOwnerReverts() (gas: 17975) TokenPool_setOnRampRateLimiterConfig:testNonExistentRampReverts() (gas: 14143) TokenPool_setOnRampRateLimiterConfig:testOnlyOwnerReverts() (gas: 17999) TokenProxy_ccipSend:testCcipSendGasShouldBeZeroReverts() (gas: 17053) -TokenProxy_ccipSend:testCcipSendInsufficientAllowanceReverts() (gas: 127348) +TokenProxy_ccipSend:testCcipSendInsufficientAllowanceReverts() (gas: 127459) TokenProxy_ccipSend:testCcipSendInvalidTokenReverts() (gas: 15839) -TokenProxy_ccipSend:testCcipSendNativeSuccess() (gas: 229327) +TokenProxy_ccipSend:testCcipSendNativeSuccess() (gas: 229567) TokenProxy_ccipSend:testCcipSendNoDataAllowedReverts() (gas: 16167) -TokenProxy_ccipSend:testCcipSendSuccess() (gas: 249231) +TokenProxy_ccipSend:testCcipSendSuccess() (gas: 249512) TokenProxy_constructor:testConstructor() (gas: 10651) TokenProxy_getFee:testGetFeeGasShouldBeZeroReverts() (gas: 16734) TokenProxy_getFee:testGetFeeInvalidTokenReverts() (gas: 12616) TokenProxy_getFee:testGetFeeNoDataAllowedReverts() (gas: 15763) -TokenProxy_getFee:testGetFeeSuccess() (gas: 73739) -USDCTokenPool__validateMessage:testValidateInvalidMessageReverts() (gas: 25129) -USDCTokenPool_lockOrBurn:testLockOrBurnWithAllowListReverts() (gas: 21826) -USDCTokenPool_lockOrBurn:testPermissionsErrorReverts() (gas: 12428) -USDCTokenPool_lockOrBurn:testUnknownDomainReverts() (gas: 183236) -USDCTokenPool_releaseOrMint:testReleaseOrMintRealTxSuccess() (gas: 55869) -USDCTokenPool_releaseOrMint:testTokenMaxCapacityExceededReverts() (gas: 27768) -USDCTokenPool_releaseOrMint:testUnlockingUSDCFailedReverts() (gas: 50610) -USDCTokenPool_setConfig:testInvalidConfigReverts() (gas: 15041) -USDCTokenPool_setConfig:testInvalidMessageVersionReverts() (gas: 11659) -USDCTokenPool_setConfig:testInvalidTokenMessengerVersionReverts() (gas: 287366) -USDCTokenPool_setConfig:testOnlyOwnerReverts() (gas: 15591) -USDCTokenPool_setConfig:testSetConfigSuccess() (gas: 345070) +TokenProxy_getFee:testGetFeeSuccess() (gas: 73961) +USDCTokenPool__validateMessage:testValidateInvalidMessageReverts() (gas: 25239) +USDCTokenPool_lockOrBurn:testLockOrBurnWithAllowListReverts() (gas: 21848) +USDCTokenPool_lockOrBurn:testPermissionsErrorReverts() (gas: 12450) +USDCTokenPool_lockOrBurn:testUnknownDomainReverts() (gas: 183254) +USDCTokenPool_releaseOrMint:testReleaseOrMintRealTxSuccess() (gas: 55891) +USDCTokenPool_releaseOrMint:testTokenMaxCapacityExceededReverts() (gas: 27790) +USDCTokenPool_releaseOrMint:testUnlockingUSDCFailedReverts() (gas: 50632) +USDCTokenPool_setConfig:testInvalidConfigReverts() (gas: 15085) +USDCTokenPool_setConfig:testInvalidMessageVersionReverts() (gas: 11681) +USDCTokenPool_setConfig:testInvalidTokenMessengerVersionReverts() (gas: 287388) +USDCTokenPool_setConfig:testOnlyOwnerReverts() (gas: 15613) +USDCTokenPool_setConfig:testSetConfigSuccess() (gas: 345224) USDCTokenPool_setDomains:testInvalidDomainReverts() (gas: 66025) USDCTokenPool_setDomains:testOnlyOwnerReverts() (gas: 15367) -USDCTokenPool_supportsInterface:testSupportsInterfaceSuccess() (gas: 8414) \ No newline at end of file +USDCTokenPool_supportsInterface:testSupportsInterfaceSuccess() (gas: 8369) \ No newline at end of file diff --git a/contracts/scripts/native_solc_compile_all_shared b/contracts/scripts/native_solc_compile_all_shared index e7199f81fe..705cedce7a 100755 --- a/contracts/scripts/native_solc_compile_all_shared +++ b/contracts/scripts/native_solc_compile_all_shared @@ -27,4 +27,5 @@ compileContract () { compileContract shared/token/ERC677/BurnMintERC677.sol compileContract shared/token/ERC677/LinkToken.sol +compileContract shared/mocks/WERC20Mock.sol compileContract vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/ERC20.sol diff --git a/contracts/scripts/native_solc_compile_all_vrf b/contracts/scripts/native_solc_compile_all_vrf index 9c142a805c..0a3b1367bd 100755 --- a/contracts/scripts/native_solc_compile_all_vrf +++ b/contracts/scripts/native_solc_compile_all_vrf @@ -55,8 +55,9 @@ compileContract mocks/VRFCoordinatorV2Mock.sol compileContract vrf/VRFOwner.sol # VRF V2Plus +compileContract dev/interfaces/IVRFCoordinatorV2PlusInternal.sol compileContract dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol -compileContractAltOpts dev/vrf/VRFCoordinatorV2Plus.sol 500 +compileContractAltOpts dev/vrf/VRFCoordinatorV2_5.sol 500 compileContract dev/vrf/BatchVRFCoordinatorV2Plus.sol compileContract dev/vrf/VRFV2PlusWrapper.sol compileContract dev/vrf/testhelpers/VRFConsumerV2PlusUpgradeableExample.sol @@ -72,6 +73,7 @@ compileContract dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol compileContract dev/vrf/TrustedBlockhashStore.sol compileContract dev/vrf/testhelpers/VRFV2PlusLoadTestWithMetrics.sol compileContractAltOpts dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol 5 +compileContract dev/vrf/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol # VRF V2 Wrapper compileContract vrf/VRFV2Wrapper.sol diff --git a/contracts/src/v0.8/ChainSpecificUtil.sol b/contracts/src/v0.8/ChainSpecificUtil.sol index 324121c9fa..088ffbd3db 100644 --- a/contracts/src/v0.8/ChainSpecificUtil.sol +++ b/contracts/src/v0.8/ChainSpecificUtil.sol @@ -18,11 +18,7 @@ library ChainSpecificUtil { function getBlockhash(uint64 blockNumber) internal view returns (bytes32) { uint256 chainid = block.chainid; - if ( - chainid == ARB_MAINNET_CHAIN_ID || - chainid == ARB_GOERLI_TESTNET_CHAIN_ID || - chainid == ARB_SEPOLIA_TESTNET_CHAIN_ID - ) { + if (isArbitrumChainId(chainid)) { if ((getBlockNumber() - blockNumber) > 256 || blockNumber >= getBlockNumber()) { return ""; } @@ -33,7 +29,7 @@ library ChainSpecificUtil { function getBlockNumber() internal view returns (uint256) { uint256 chainid = block.chainid; - if (chainid == ARB_MAINNET_CHAIN_ID || chainid == ARB_GOERLI_TESTNET_CHAIN_ID) { + if (isArbitrumChainId(chainid)) { return ARBSYS.arbBlockNumber(); } return block.number; @@ -41,7 +37,7 @@ library ChainSpecificUtil { function getCurrentTxL1GasFees() internal view returns (uint256) { uint256 chainid = block.chainid; - if (chainid == ARB_MAINNET_CHAIN_ID || chainid == ARB_GOERLI_TESTNET_CHAIN_ID) { + if (isArbitrumChainId(chainid)) { return ARBGAS.getCurrentTxL1GasFees(); } return 0; @@ -53,7 +49,7 @@ library ChainSpecificUtil { */ function getL1CalldataGasCost(uint256 calldataSizeBytes) internal view returns (uint256) { uint256 chainid = block.chainid; - if (chainid == ARB_MAINNET_CHAIN_ID || chainid == ARB_GOERLI_TESTNET_CHAIN_ID) { + if (isArbitrumChainId(chainid)) { (, uint256 l1PricePerByte, , , , ) = ARBGAS.getPricesInWei(); // see https://developer.arbitrum.io/devs-how-tos/how-to-estimate-gas#where-do-we-get-all-this-information-from // for the justification behind the 140 number. @@ -61,4 +57,14 @@ library ChainSpecificUtil { } return 0; } + + /** + * @notice Return true if and only if the provided chain ID is an Arbitrum chain ID. + */ + function isArbitrumChainId(uint256 chainId) internal pure returns (bool) { + return + chainId == ARB_MAINNET_CHAIN_ID || + chainId == ARB_GOERLI_TESTNET_CHAIN_ID || + chainId == ARB_SEPOLIA_TESTNET_CHAIN_ID; + } } diff --git a/contracts/src/v0.8/ccip/ARM.sol b/contracts/src/v0.8/ccip/ARM.sol index c98258463d..2a715ef1f6 100644 --- a/contracts/src/v0.8/ccip/ARM.sol +++ b/contracts/src/v0.8/ccip/ARM.sol @@ -1,12 +1,12 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {IARM} from "./interfaces/IARM.sol"; import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; -contract ARM is IARM, OwnerIsCreator, TypeAndVersionInterface { +contract ARM is IARM, OwnerIsCreator, ITypeAndVersion { // STATIC CONFIG // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables string public constant override typeAndVersion = "ARM 1.0.0"; @@ -115,6 +115,7 @@ contract ARM is IARM, OwnerIsCreator, TypeAndVersionInterface { // EVENTS, ERRORS event ConfigSet(uint32 indexed configVersion, Config config); + error InvalidConfig(); event TaggedRootBlessed(uint32 indexed configVersion, IARM.TaggedRoot taggedRoot, uint16 accumulatedWeight); diff --git a/contracts/src/v0.8/ccip/ARMProxy.sol b/contracts/src/v0.8/ccip/ARMProxy.sol index 7357601448..aa382e8bf2 100644 --- a/contracts/src/v0.8/ccip/ARMProxy.sol +++ b/contracts/src/v0.8/ccip/ARMProxy.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; @@ -10,7 +10,7 @@ import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; /// since each contract need not store an ARM address in storage. That way /// we can add ARM queries along many code paths for increased defense in depth /// with minimal additional cost. -contract ARMProxy is OwnerIsCreator, TypeAndVersionInterface { +contract ARMProxy is OwnerIsCreator, ITypeAndVersion { error ZeroAddressNotAllowed(); event ARMSet(address arm); diff --git a/contracts/src/v0.8/ccip/CommitStore.sol b/contracts/src/v0.8/ccip/CommitStore.sol index bff308f2bf..905a8cde67 100644 --- a/contracts/src/v0.8/ccip/CommitStore.sol +++ b/contracts/src/v0.8/ccip/CommitStore.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {ICommitStore} from "./interfaces/ICommitStore.sol"; import {IARM} from "./interfaces/IARM.sol"; import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; @@ -10,7 +10,7 @@ import {OCR2Base} from "./ocr/OCR2Base.sol"; import {Internal} from "./libraries/Internal.sol"; import {MerkleMultiProof} from "./libraries/MerkleMultiProof.sol"; -contract CommitStore is ICommitStore, TypeAndVersionInterface, OCR2Base { +contract CommitStore is ICommitStore, ITypeAndVersion, OCR2Base { error StaleReport(); error PausedError(); error InvalidInterval(Interval interval); @@ -184,7 +184,7 @@ contract CommitStore is ICommitStore, TypeAndVersionInterface, OCR2Base { CommitReport memory report = abi.decode(encodedReport, (CommitReport)); // Check if the report contains price updates - if (report.priceUpdates.tokenPriceUpdates.length > 0 || report.priceUpdates.destChainSelector != 0) { + if (report.priceUpdates.tokenPriceUpdates.length > 0 || report.priceUpdates.gasPriceUpdates.length > 0) { // Check for price staleness based on the epoch and round if (s_latestPriceEpochAndRound < epochAndRound) { // If prices are not stale, update the latest epoch and round diff --git a/contracts/src/v0.8/ccip/PriceRegistry.sol b/contracts/src/v0.8/ccip/PriceRegistry.sol index ec7089fc0d..e13ea6cfed 100644 --- a/contracts/src/v0.8/ccip/PriceRegistry.sol +++ b/contracts/src/v0.8/ccip/PriceRegistry.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {IPriceRegistry} from "./interfaces/IPriceRegistry.sol"; -import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; import {OwnerIsCreator} from "./../shared/access/OwnerIsCreator.sol"; import {Internal} from "./libraries/Internal.sol"; @@ -12,7 +12,7 @@ import {EnumerableSet} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/ut /// @notice The PriceRegistry contract responsibility is to store the current gas price in USD for a given destination chain, /// and the price of a token in USD allowing the owner or priceUpdater to update this value. -contract PriceRegistry is IPriceRegistry, OwnerIsCreator, TypeAndVersionInterface { +contract PriceRegistry is IPriceRegistry, OwnerIsCreator, ITypeAndVersion { using EnumerableSet for EnumerableSet.AddressSet; using USDPriceWith18Decimals for uint224; @@ -190,9 +190,9 @@ contract PriceRegistry is IPriceRegistry, OwnerIsCreator, TypeAndVersionInterfac // @inheritdoc IPriceRegistry function updatePrices(Internal.PriceUpdates calldata priceUpdates) external override requireUpdaterOrOwner { - uint256 priceUpdatesLength = priceUpdates.tokenPriceUpdates.length; + uint256 tokenUpdatesLength = priceUpdates.tokenPriceUpdates.length; - for (uint256 i = 0; i < priceUpdatesLength; ++i) { + for (uint256 i = 0; i < tokenUpdatesLength; ++i) { Internal.TokenPriceUpdate memory update = priceUpdates.tokenPriceUpdates[i]; s_usdPerToken[update.sourceToken] = Internal.TimestampedPackedUint224({ value: update.usdPerToken, @@ -201,12 +201,15 @@ contract PriceRegistry is IPriceRegistry, OwnerIsCreator, TypeAndVersionInterfac emit UsdPerTokenUpdated(update.sourceToken, update.usdPerToken, block.timestamp); } - if (priceUpdates.destChainSelector != 0) { - s_usdPerUnitGasByDestChainSelector[priceUpdates.destChainSelector] = Internal.TimestampedPackedUint224({ - value: priceUpdates.usdPerUnitGas, + uint256 gasUpdatesLength = priceUpdates.gasPriceUpdates.length; + + for (uint256 i = 0; i < gasUpdatesLength; ++i) { + Internal.GasPriceUpdate memory update = priceUpdates.gasPriceUpdates[i]; + s_usdPerUnitGasByDestChainSelector[update.destChainSelector] = Internal.TimestampedPackedUint224({ + value: update.usdPerUnitGas, timestamp: uint32(block.timestamp) }); - emit UsdPerUnitGasUpdated(priceUpdates.destChainSelector, priceUpdates.usdPerUnitGas, block.timestamp); + emit UsdPerUnitGasUpdated(update.destChainSelector, update.usdPerUnitGas, block.timestamp); } } diff --git a/contracts/src/v0.8/ccip/Router.sol b/contracts/src/v0.8/ccip/Router.sol index 3cdb5f8d15..7cd0464134 100644 --- a/contracts/src/v0.8/ccip/Router.sol +++ b/contracts/src/v0.8/ccip/Router.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {TypeAndVersionInterface} from "../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../shared/interfaces/ITypeAndVersion.sol"; import {IRouterClient} from "./interfaces/IRouterClient.sol"; import {IRouter} from "./interfaces/IRouter.sol"; import {IEVM2AnyOnRamp} from "./interfaces/IEVM2AnyOnRamp.sol"; @@ -19,7 +19,7 @@ import {IERC20} from "../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC /// @title Router /// @notice This is the entry point for the end user wishing to send data across chains. /// @dev This contract is used as a router for both on-ramps and off-ramps -contract Router is IRouter, IRouterClient, TypeAndVersionInterface, OwnerIsCreator { +contract Router is IRouter, IRouterClient, ITypeAndVersion, OwnerIsCreator { using SafeERC20 for IERC20; using EnumerableMap for EnumerableMap.AddressToUintMap; diff --git a/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol b/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol index 801d8af0c6..cbeb64a3e3 100644 --- a/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol +++ b/contracts/src/v0.8/ccip/applications/CCIPReceiver.sol @@ -26,7 +26,7 @@ abstract contract CCIPReceiver is IAny2EVMMessageReceiver, IERC165 { /// If this returns true, tokens are transferred and ccipReceive is called atomically. /// Additionally, if the receiver address does not have code associated with /// it at the time of execution (EXTCODESIZE returns 0), only tokens will be transferred. - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) { return interfaceId == type(IAny2EVMMessageReceiver).interfaceId || interfaceId == type(IERC165).interfaceId; } diff --git a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol index 583d752d8d..952bc7a59a 100644 --- a/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol +++ b/contracts/src/v0.8/ccip/interfaces/IPriceRegistry.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; import {Internal} from "../libraries/Internal.sol"; interface IPriceRegistry { - /// @notice Update the price for given tokens and destination chain. + /// @notice Update the price for given tokens and gas prices for given chains. /// @param priceUpdates The price updates to apply. function updatePrices(Internal.PriceUpdates memory priceUpdates) external; diff --git a/contracts/src/v0.8/ccip/libraries/Internal.sol b/contracts/src/v0.8/ccip/libraries/Internal.sol index d314553f20..d14e0380f0 100644 --- a/contracts/src/v0.8/ccip/libraries/Internal.sol +++ b/contracts/src/v0.8/ccip/libraries/Internal.sol @@ -8,8 +8,7 @@ import {MerkleMultiProof} from "../libraries/MerkleMultiProof.sol"; library Internal { struct PriceUpdates { TokenPriceUpdate[] tokenPriceUpdates; - uint64 destChainSelector; // ──╮ Destination chain selector - uint224 usdPerUnitGas; // ─────╯ 1e18 USD per smallest unit (e.g. wei) of destination chain gas + GasPriceUpdate[] gasPriceUpdates; } struct TokenPriceUpdate { @@ -17,6 +16,11 @@ library Internal { uint224 usdPerToken; // 1e18 USD per smallest unit of token } + struct GasPriceUpdate { + uint64 destChainSelector; // Destination chain selector + uint224 usdPerUnitGas; // 1e18 USD per smallest unit (e.g. wei) of destination chain gas + } + struct TimestampedPackedUint224 { uint224 value; // ───────╮ Value in uint224, packed. uint32 timestamp; // ────╯ Timestamp of the most recent price update. @@ -65,8 +69,8 @@ library Internal { uint256 public constant MESSAGE_FIXED_BYTES = 32 * 17; /// @dev Each token transfer adds 1 EVMTokenAmount and 1 bytes. - /// When abiEncoded, each EVMTokenAmount takes 2 slots, each bytes takes 2 slots. - uint256 public constant MESSAGE_BYTES_PER_TOKEN = 32 * 4; + /// When abiEncoded, each EVMTokenAmount takes 2 slots, each bytes takes 2 slots, excl bytes contents + uint256 public constant MESSAGE_FIXED_BYTES_PER_TOKEN = 32 * 4; function _toAny2EVMMessage( EVM2EVMMessage memory original, diff --git a/contracts/src/v0.8/ccip/ocr/OCR2Abstract.sol b/contracts/src/v0.8/ccip/ocr/OCR2Abstract.sol index 3c543f534c..741433bd5a 100644 --- a/contracts/src/v0.8/ccip/ocr/OCR2Abstract.sol +++ b/contracts/src/v0.8/ccip/ocr/OCR2Abstract.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.0; -import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../../shared/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 MAX_NUM_ORACLES = 31; diff --git a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol index b1c5cd2482..a727f0ee37 100644 --- a/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol +++ b/contracts/src/v0.8/ccip/offRamp/EVM2EVMOffRamp.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; import {ICommitStore} from "../interfaces/ICommitStore.sol"; import {IARM} from "../interfaces/IARM.sol"; import {IPool} from "../interfaces/pools/IPool.sol"; @@ -28,7 +28,7 @@ import {ERC165Checker} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts /// @dev OCR2BaseNoChecks is used to save gas, signatures are not required as the offramp can only execute /// messages which are committed in the commitStore. We still make use of OCR2 as an executor whitelist /// and turn-taking mechanism. -contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, TypeAndVersionInterface, OCR2BaseNoChecks { +contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, ITypeAndVersion, OCR2BaseNoChecks { using Address for address; using ERC165Checker for address; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; @@ -380,7 +380,7 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, TypeAndVersion try this.executeSingleMessage(message, offchainTokenData) {} catch (bytes memory err) { if (ReceiverError.selector == bytes4(err) || TokenHandlingError.selector == bytes4(err)) { // If CCIP receiver execution is not successful, bubble up receiver revert data, - // prepended by the 4 bytes of ReceiverError.selector + // prepended by the 4 bytes of ReceiverError.selector or TokenHandlingError.selector // Max length of revert data is Router.MAX_RET_BYTES, max length of err is 4 + Router.MAX_RET_BYTES return (Internal.MessageExecutionState.FAILURE, err); } else { @@ -589,23 +589,9 @@ contract EVM2EVMOffRamp is IAny2EVMOffRamp, AggregateRateLimiter, TypeAndVersion i_sourceChainSelector, abi.encode(sourceTokenData[i], offchainTokenData[i]) ) - {} catch ( - /// @dev we only want to revert on rate limiting errors, any other errors are - /// wrapped in a TokenHandlingError, which is caught above and handled gracefully. - bytes memory err - ) { - bytes4 errSig = bytes4(err); - if ( - RateLimiter.BucketOverfilled.selector == errSig || - RateLimiter.AggregateValueMaxCapacityExceeded.selector == errSig || - RateLimiter.AggregateValueRateLimitReached.selector == errSig || - RateLimiter.TokenMaxCapacityExceeded.selector == errSig || - RateLimiter.TokenRateLimitReached.selector == errSig - ) { - revert TokenRateLimitError(err); - } else { - revert TokenHandlingError(err); - } + {} catch (bytes memory err) { + /// @dev wrap and rethrow the error so we can catch it lower in the stack + revert TokenHandlingError(err); } destTokenAmounts[i].token = address(pool.getToken()); diff --git a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol index 7385e7c055..2f1e793218 100644 --- a/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol +++ b/contracts/src/v0.8/ccip/onRamp/EVM2EVMOnRamp.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; -import {TypeAndVersionInterface} from "../../interfaces/TypeAndVersionInterface.sol"; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; import {IPool} from "../interfaces/pools/IPool.sol"; import {IARM} from "../interfaces/IARM.sol"; import {IPriceRegistry} from "../interfaces/IPriceRegistry.sol"; @@ -23,7 +23,7 @@ import {EnumerableMap} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts /// bridgeable token support. /// @dev The EVM2EVMOnRamp, CommitStore and EVM2EVMOffRamp form an xchain upgradeable unit. Any change to one of them /// results an onchain upgrade of all 3. -contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, TypeAndVersionInterface { +contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, ITypeAndVersion { using SafeERC20 for IERC20; using EnumerableMap for EnumerableMap.AddressToUintMap; using EnumerableMapAddresses for EnumerableMapAddresses.AddressToAddressMap; @@ -81,10 +81,10 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, address router; // ─────────────────────────╮ Router address uint16 maxTokensLength; // │ Maximum number of ERC20 token transfers per message uint32 destGasOverhead; // │ Extra gas charged on top of the gasLimit - uint16 destGasPerPayloadByte; // │ Destination chain gas charged per byte of `data` payload - uint32 destDataAvailabilityOverheadGas; // │ Extra data availability gas charged on top of message data - uint16 destGasPerDataAvailabilityByte; // ──╯ Amount of gas to charge per byte of data that needs availability - uint16 destDataAvailabilityMultiplier; // ──╮ Multiplier for data availability gas, multiples of 1e-4, or 0.0001 + uint16 destGasPerPayloadByte; // │ Destination chain gas charged for passing each byte of `data` payload to receiver + uint32 destDataAvailabilityOverheadGas; // ─╯ Extra data availability gas charged on top of the message, e.g. for OCR + uint16 destGasPerDataAvailabilityByte; // ──╮Amount of gas to charge per byte of message data that needs availability + uint16 destDataAvailabilityMultiplier; // │ Multiplier for data availability gas, multiples of 1e-4, or 0.0001 address priceRegistry; // │ Price registry address uint32 maxDataSize; // │ Maximum payload data size, max 4GB uint32 maxGasLimit; // ─────────────────────╯ Maximum gas limit for messages targeting EVMs, max 4 Billion gas @@ -93,8 +93,6 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, /// @dev Struct to hold the execution fee configuration for a fee token struct FeeTokenConfig { uint32 networkFeeUSD; // ───────────╮ Flat network fee to charge for messages, multiples of 0.01 USD - uint32 minTokenTransferFeeUSD; // │ Minimum fee to charge for token transfers, multiples of 0.01 USD - uint32 maxTokenTransferFeeUSD; // │ Maximum fee to charge for token transfers, multiples of 0.01 USD uint64 gasMultiplier; // │ Price multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost. uint64 premiumMultiplier; // │ Multiplier for fee-token-specific premiums bool enabled; // ───────────────────╯ Whether this fee token is enabled @@ -105,27 +103,29 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, struct FeeTokenConfigArgs { address token; // ──────────────────╮ Token address uint32 networkFeeUSD; // │ Flat network fee to charge for messages, multiples of 0.01 USD - uint32 minTokenTransferFeeUSD; // │ Minimum fee to charge for token transfers, multiples of 0.01 USD - uint32 maxTokenTransferFeeUSD; //───╯ Maximum fee to charge for token transfers, multiples of 0.01 USD - uint64 gasMultiplier; // ───╮ Price multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost - uint64 premiumMultiplier; // │ Multiplier for fee-token-specific premiums + uint64 gasMultiplier; // ───────────╯ Price multiplier for gas costs, 1e18 based so 11e17 = 10% extra cost + uint64 premiumMultiplier; // ───────╮ Multiplier for fee-token-specific premiums bool enabled; // ───────────────────╯ Whether this fee token is enabled } /// @dev Struct to hold the transfer fee configuration for token transfers struct TokenTransferFeeConfig { - uint16 ratio; // ───────────────────╮ Ratio of token transfer value to charge as fee, multiples of 0.1bps, or 1e-5 + uint32 minFeeUSD; // ───────────────╮ Minimum fee to charge per token transfer, multiples of 0.01 USD + uint32 maxFeeUSD; // │ Maximum fee to charge per token transfer, multiples of 0.01 USD + uint16 ratio; // │ Ratio of token transfer value to charge as fee, multiples of 0.1bps, or 1e-5 uint32 destGasOverhead; // │ Gas charged to execute the token transfer on the destination chain - uint32 destBytesOverhead; // ───────╯ Extra data availability bytes on top of transfer data, e.g. USDC offchain data + uint32 destBytesOverhead; // ───────╯ Extra data availability bytes on top of fixed transfer data, e.g. USDC source token data and offchain data } /// @dev Same as TokenTransferFeeConfig /// token included so that an array of these can be passed in to setTokenTransferFeeConfig struct TokenTransferFeeConfigArgs { address token; // ──────────────────╮ Token address - uint16 ratio; // │ Ratio of token transfer value to charge as fee, multiples of 0.1bps, or 1e-5 - uint32 destGasOverhead; // │ Gas charged to execute the token transfer on the destination chain - uint32 destBytesOverhead; // ───────╯ Extra data availability bytes on top of transfer data, e.g. USDC offchain data + uint32 minFeeUSD; // │ Minimum fee to charge per token transfer, multiples of 0.01 USD + uint32 maxFeeUSD; // │ Maximum fee to charge per token transfer, multiples of 0.01 USD + uint16 ratio; // ───────────────────╯ Ratio of token transfer value to charge as fee, multiples of 0.1bps, or 1e-5 + uint32 destGasOverhead; // ─────────╮ Gas charged to execute the token transfer on the destination chain + uint32 destBytesOverhead; // ───────╯ Extra data availability bytes on top of fixed transfer data, e.g. USDC source token data and offchain data } /// @dev Nop address and weight, used to set the nops and their weights @@ -495,8 +495,9 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, uint112 executionGasPrice = uint112(packedGasPrice); // Calculate premiumFee in USD with 18 decimals precision. - // If there are token transfers, premiumFee is calculated from token transfer fees. - // If there are no token transfers, we charge a flat network fee. + // If message-only and no token transfers, a flat network fee is charged. + // If there are token transfers, premiumFee is calculated from token transfer fee. + // If there are both token transfers and message, premiumFee is only calculated from token transfer fee. uint256 premiumFeeUSD = 0; uint32 tokenTransferGas = 0; uint32 tokenTransferBytesOverhead = 0; @@ -504,8 +505,7 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, (premiumFeeUSD, tokenTransferGas, tokenTransferBytesOverhead) = _getTokenTransferCost( message.feeToken, feeTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); } else { // Convert USD values with 2 decimals to 18 decimals. @@ -559,9 +559,10 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, ) internal view returns (uint256 dataAvailabilityCostUSD) { uint256 dataAvailabilityLengthBytes = Internal.MESSAGE_FIXED_BYTES + messageDataLength + - (numberOfTokens * Internal.MESSAGE_BYTES_PER_TOKEN) + + (numberOfTokens * Internal.MESSAGE_FIXED_BYTES_PER_TOKEN) + tokenTransferBytesOverhead; + // destDataAvailabilityOverheadGas is a separate config value for flexibility to be updated independently of message cost. uint256 dataAvailabilityGas = (dataAvailabilityLengthBytes * s_dynamicConfig.destGasPerDataAvailabilityByte) + s_dynamicConfig.destDataAvailabilityOverheadGas; @@ -572,22 +573,21 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, /// @notice Returns the token transfer fee. /// A basis point fee is calculated from the USD value of each token transfer. - /// Sum of basis point fees is confined within range [minTokenTransferFeeUSD, maxTokenTransferFeeUSD]. + /// For each individual transfer, this fee is between [minFeeUSD, maxFeeUSD]. + /// Total transfer fee is the sum of each individual token transfer fee. /// @dev Assumes that tokenAmounts are validated to be listed tokens elsewhere. /// @dev Splitting one token transfer into multiple transfers is discouraged, /// as it will result in a transferFee equal or greater than the same amount aggregated/de-duped. /// @param feeToken address of the feeToken. /// @param feeTokenPrice price of feeToken in USD with 18 decimals. /// @param tokenAmounts token transfers in the message. - /// @param feeTokenConfig configuration struct of fee token. /// @return tokenTransferFeeUSD total token transfer bps fee in USD with 36 decimals. /// @return tokenTransferGas total execution gas of the token transfers. /// @return tokenTransferBytesOverhead additional token transfer data passed to destination, e.g. USDC attestation. function _getTokenTransferCost( address feeToken, uint224 feeTokenPrice, - Client.EVMTokenAmount[] calldata tokenAmounts, - FeeTokenConfig memory feeTokenConfig + Client.EVMTokenAmount[] calldata tokenAmounts ) internal view returns (uint256 tokenTransferFeeUSD, uint32 tokenTransferGas, uint32 tokenTransferBytesOverhead) { uint256 numberOfTokens = tokenAmounts.length; @@ -614,21 +614,24 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, bpsFeeUSD = (tokenPrice._calcUSDValueFromTokenAmount(tokenAmount.amount) * transferFeeConfig.ratio) / 1e5; } - tokenTransferFeeUSD += bpsFeeUSD; tokenTransferGas += transferFeeConfig.destGasOverhead; tokenTransferBytesOverhead += transferFeeConfig.destBytesOverhead; - } - // Convert USD values with 2 decimals to 18 decimals. - // Sum of bps fees should be kept within range of [minTokenTransferFeeUSD, maxTokenTransferFeeUSD]. - uint256 minTransferFeeUSD = uint256(feeTokenConfig.minTokenTransferFeeUSD) * 1e16; - if (tokenTransferFeeUSD < minTransferFeeUSD) { - return (minTransferFeeUSD, tokenTransferGas, tokenTransferBytesOverhead); - } + // Bps fees should be kept within range of [minFeeUSD, maxFeeUSD]. + // Convert USD values with 2 decimals to 18 decimals. + uint256 minFeeUSD = uint256(transferFeeConfig.minFeeUSD) * 1e16; + if (bpsFeeUSD < minFeeUSD) { + tokenTransferFeeUSD += minFeeUSD; + continue; + } - uint256 maxTransferFeeUSD = uint256(feeTokenConfig.maxTokenTransferFeeUSD) * 1e16; - if (tokenTransferFeeUSD > maxTransferFeeUSD) { - return (maxTransferFeeUSD, tokenTransferGas, tokenTransferBytesOverhead); + uint256 maxFeeUSD = uint256(transferFeeConfig.maxFeeUSD) * 1e16; + if (bpsFeeUSD > maxFeeUSD) { + tokenTransferFeeUSD += maxFeeUSD; + continue; + } + + tokenTransferFeeUSD += bpsFeeUSD; } return (tokenTransferFeeUSD, tokenTransferGas, tokenTransferBytesOverhead); @@ -655,8 +658,6 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, s_feeTokenConfig[configArg.token] = FeeTokenConfig({ networkFeeUSD: configArg.networkFeeUSD, - minTokenTransferFeeUSD: configArg.minTokenTransferFeeUSD, - maxTokenTransferFeeUSD: configArg.maxTokenTransferFeeUSD, gasMultiplier: configArg.gasMultiplier, premiumMultiplier: configArg.premiumMultiplier, enabled: configArg.enabled @@ -686,6 +687,8 @@ contract EVM2EVMOnRamp is IEVM2AnyOnRamp, ILinkAvailable, AggregateRateLimiter, TokenTransferFeeConfigArgs memory configArg = tokenTransferFeeConfigArgs[i]; s_tokenTransferFeeConfig[configArg.token] = TokenTransferFeeConfig({ + minFeeUSD: configArg.minFeeUSD, + maxFeeUSD: configArg.maxFeeUSD, ratio: configArg.ratio, destGasOverhead: configArg.destGasOverhead, destBytesOverhead: configArg.destBytesOverhead diff --git a/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol b/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol index 1649057e8c..713679711e 100644 --- a/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/BurnMintTokenPool.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; + import {IBurnMintERC20} from "../../shared/token/ERC20/IBurnMintERC20.sol"; import {TokenPool} from "./TokenPool.sol"; @@ -10,7 +12,10 @@ import {TokenPool} from "./TokenPool.sol"; /// It either accepts any address as originalSender, or only accepts whitelisted originalSender. /// The only way to change whitelisting mode is to deploy a new pool. /// If that is expected, please make sure the token's burner/minter roles are adjustable. -contract BurnMintTokenPool is TokenPool { +contract BurnMintTokenPool is TokenPool, ITypeAndVersion { + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables + string public constant override typeAndVersion = "BurnMintTokenPool 1.2.0"; + constructor( IBurnMintERC20 token, address[] memory allowlist, diff --git a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol index df8ec6adb2..4f2dc14d69 100644 --- a/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/LockReleaseTokenPool.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; +import {ITypeAndVersion} from "../../shared/interfaces/ITypeAndVersion.sol"; + import {TokenPool} from "./TokenPool.sol"; import {IERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/token/ERC20/IERC20.sol"; @@ -10,7 +12,7 @@ import {SafeERC20} from "../../vendor/openzeppelin-solidity/v4.8.0/contracts/tok /// Because of lock/unlock requiring liquidity, this pool contract also has function to add and remove /// liquidity. This allows for proper bookkeeping for both user and liquidity provider balances. /// @dev One token per LockReleaseTokenPool. -contract LockReleaseTokenPool is TokenPool { +contract LockReleaseTokenPool is TokenPool, ITypeAndVersion { using SafeERC20 for IERC20; event LiquidityAdded(address indexed provider, uint256 indexed amount); @@ -20,6 +22,9 @@ contract LockReleaseTokenPool is TokenPool { error WithdrawalTooHigh(); error LiquidityNotAccepted(); + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables + string public constant override typeAndVersion = "LockReleaseTokenPool 1.2.0"; + /// @dev The unique lock release pool flag to signal through EIP 165. bytes4 private constant LOCK_RELEASE_INTERFACE_ID = bytes4(keccak256("LockReleaseTokenPool")); diff --git a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol index 01e8207e38..8773e83ba9 100644 --- a/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol +++ b/contracts/src/v0.8/ccip/pools/USDC/USDCTokenPool.sol @@ -1,6 +1,7 @@ // SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; +import {ITypeAndVersion} from "../../../shared/interfaces/ITypeAndVersion.sol"; import {IBurnMintERC20} from "../../../shared/token/ERC20/IBurnMintERC20.sol"; import {ITokenMessenger} from "./ITokenMessenger.sol"; import {IMessageReceiver} from "./IMessageReceiver.sol"; @@ -9,7 +10,7 @@ import {TokenPool} from "../TokenPool.sol"; /// @notice This pool mints and burns USDC tokens through the Cross Chain Transfer /// Protocol (CCTP). -contract USDCTokenPool is TokenPool { +contract USDCTokenPool is TokenPool, ITypeAndVersion { event DomainsSet(DomainUpdate[]); event ConfigSet(USDCConfig); @@ -50,6 +51,9 @@ contract USDCTokenPool is TokenPool { uint32 sourceDomain; } + // solhint-disable-next-line chainlink-solidity/all-caps-constant-storage-variables + string public constant override typeAndVersion = "USDCTokenPool 1.2.0"; + uint32 public immutable i_localDomainIdentifier; uint32 public constant SUPPORTED_USDC_VERSION = 0; diff --git a/contracts/src/v0.8/ccip/test/StructFactory.sol b/contracts/src/v0.8/ccip/test/StructFactory.sol index 10d41a5308..c6ce98f6fe 100644 --- a/contracts/src/v0.8/ccip/test/StructFactory.sol +++ b/contracts/src/v0.8/ccip/test/StructFactory.sol @@ -181,7 +181,7 @@ contract StructFactory { return RateLimiter.Config({isEnabled: true, capacity: 100e28, rate: 1e15}); } - function getSinglePriceUpdateStruct( + function getSingleTokenPriceUpdateStruct( address token, uint224 price ) internal pure returns (Internal.PriceUpdates memory) { @@ -190,13 +190,38 @@ contract StructFactory { Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); return priceUpdates; } + function getSingleGasPriceUpdateStruct( + uint64 chainSelector, + uint224 usdPerUnitGas + ) internal pure returns (Internal.PriceUpdates memory) { + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: chainSelector, usdPerUnitGas: usdPerUnitGas}); + + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: gasPriceUpdates + }); + + return priceUpdates; + } + + function getSingleTokenAndGasPriceUpdateStruct( + address token, + uint224 price, + uint64 chainSelector, + uint224 usdPerUnitGas + ) internal pure returns (Internal.PriceUpdates memory) { + Internal.PriceUpdates memory update = getSingleTokenPriceUpdateStruct(token, price); + update.gasPriceUpdates = getSingleGasPriceUpdateStruct(chainSelector, usdPerUnitGas).gasPriceUpdates; + return update; + } + function getPriceUpdatesStruct( address[] memory tokens, uint224[] memory prices @@ -209,8 +234,7 @@ contract StructFactory { } Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); return priceUpdates; @@ -221,8 +245,7 @@ contract StructFactory { return Internal.PriceUpdates({ tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); } } diff --git a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol index 09feea1811..3f0cf6f962 100644 --- a/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol +++ b/contracts/src/v0.8/ccip/test/commitStore/CommitStore.t.sol @@ -346,7 +346,7 @@ contract CommitStore_report is CommitStoreSetup { uint64 max1 = 12; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(1, max1), merkleRoot: "test #2" }); @@ -367,7 +367,7 @@ contract CommitStore_report is CommitStoreSetup { .value; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(1, maxSeq), merkleRoot: "stale report 1" }); @@ -397,9 +397,23 @@ contract CommitStore_report is CommitStoreSetup { ); } - function testOnlyPriceUpdatesSuccess() public { + function testOnlyTokenPriceUpdatesSuccess() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), + interval: CommitStore.Interval(0, 0), + merkleRoot: "" + }); + + vm.expectEmit(); + emit UsdPerTokenUpdated(s_sourceFeeToken, 4e18, block.timestamp); + + s_commitStore.report(abi.encode(report), ++s_latestEpochAndRound); + assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); + } + + function testOnlyGasPriceUpdatesSuccess() public { + CommitStore.CommitReport memory report = CommitStore.CommitReport({ + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: "" }); @@ -417,7 +431,7 @@ contract CommitStore_report is CommitStoreSetup { uint224 tokenPrice2 = 5e18; CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, tokenPrice1), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice1), interval: CommitStore.Interval(0, 0), merkleRoot: "" }); @@ -429,7 +443,7 @@ contract CommitStore_report is CommitStoreSetup { assertEq(s_latestEpochAndRound, s_commitStore.getLatestPriceEpochAndRound()); report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, tokenPrice2), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, tokenPrice2), interval: CommitStore.Interval(1, maxSeq), merkleRoot: "stale report" }); @@ -502,7 +516,7 @@ contract CommitStore_report is CommitStoreSetup { function testZeroEpochAndRoundReverts() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: bytes32(0) }); @@ -514,7 +528,7 @@ contract CommitStore_report is CommitStoreSetup { function testOnlyPriceUpdateStaleReportReverts() public { CommitStore.CommitReport memory report = CommitStore.CommitReport({ - priceUpdates: getSinglePriceUpdateStruct(s_sourceFeeToken, 4e18), + priceUpdates: getSingleTokenPriceUpdateStruct(s_sourceFeeToken, 4e18), interval: CommitStore.Interval(0, 0), merkleRoot: bytes32(0) }); diff --git a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOnRampHelper.sol b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOnRampHelper.sol index dbe54f3969..ede4943a43 100644 --- a/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOnRampHelper.sol +++ b/contracts/src/v0.8/ccip/test/helpers/EVM2EVMOnRampHelper.sol @@ -43,9 +43,8 @@ contract EVM2EVMOnRampHelper is EVM2EVMOnRamp, IgnoreContractSize { function getTokenTransferCost( address feeToken, uint224 feeTokenPrice, - Client.EVMTokenAmount[] calldata tokenAmounts, - FeeTokenConfig memory feeTokenConfig + Client.EVMTokenAmount[] calldata tokenAmounts ) external view returns (uint256, uint32, uint32) { - return _getTokenTransferCost(feeToken, feeTokenPrice, tokenAmounts, feeTokenConfig); + return _getTokenTransferCost(feeToken, feeTokenPrice, tokenAmounts); } } diff --git a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol index 2bc9faa0ac..c7acc21f7b 100644 --- a/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/offRamp/EVM2EVMOffRamp.t.sol @@ -1102,12 +1102,12 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { IERC20 dstToken0 = IERC20(s_destTokens[0]); uint256 startingBalance = dstToken0.balanceOf(message.receiver); - (Internal.MessageExecutionState newState, bytes memory error) = s_offRamp.trialExecute( + (Internal.MessageExecutionState newState, bytes memory err) = s_offRamp.trialExecute( message, new bytes[](message.tokenAmounts.length) ); assertEq(uint256(Internal.MessageExecutionState.SUCCESS), uint256(newState)); - assertEq("", error); + assertEq("", err); // Check that the tokens were transferred assertEq(startingBalance + amounts[0], dstToken0.balanceOf(message.receiver)); @@ -1126,20 +1126,18 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); MaybeRevertingBurnMintTokenPool(s_destPools[1]).setShouldRevert(errorMessage); - (Internal.MessageExecutionState newState, bytes memory error) = s_offRamp.trialExecute( + (Internal.MessageExecutionState newState, bytes memory err) = s_offRamp.trialExecute( message, new bytes[](message.tokenAmounts.length) ); assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); - assertEq(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, errorMessage), error); + assertEq(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, errorMessage), err); // Expect the balance to remain the same assertEq(startingBalance, dstToken0.balanceOf(OWNER)); } - // Reverts - - function testRateLimitErrorReverts() public { + function testRateLimitErrorSuccess() public { uint256[] memory amounts = new uint256[](2); amounts[0] = 1000; amounts[1] = 50; @@ -1149,14 +1147,12 @@ contract EVM2EVMOffRamp__trialExecute is EVM2EVMOffRampSetup { Internal.EVM2EVMMessage memory message = _generateAny2EVMMessageWithTokens(1, amounts); MaybeRevertingBurnMintTokenPool(s_destPools[1]).setShouldRevert(errorMessage); - vm.expectRevert( - abi.encodeWithSelector( - EVM2EVMOffRamp.ExecutionError.selector, - abi.encodeWithSelector(EVM2EVMOffRamp.TokenRateLimitError.selector, errorMessage) - ) + (Internal.MessageExecutionState newState, bytes memory err) = s_offRamp.trialExecute( + message, + new bytes[](message.tokenAmounts.length) ); - - s_offRamp.trialExecute(message, new bytes[](message.tokenAmounts.length)); + assertEq(uint256(Internal.MessageExecutionState.FAILURE), uint256(newState)); + assertEq(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, errorMessage), err); } } @@ -1244,7 +1240,7 @@ contract EVM2EVMOffRamp__releaseOrMintTokens is EVM2EVMOffRampSetup { for (uint256 i = 0; i < rateLimitErrors.length; ++i) { MaybeRevertingBurnMintTokenPool(s_destPools[1]).setShouldRevert(rateLimitErrors[i]); - vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenRateLimitError.selector, rateLimitErrors[i])); + vm.expectRevert(abi.encodeWithSelector(EVM2EVMOffRamp.TokenHandlingError.selector, rateLimitErrors[i])); s_offRamp.releaseOrMintTokens( srcTokenAmounts, diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol index 838c0e3cf9..2439c65d62 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRamp.t.sol @@ -453,7 +453,7 @@ contract EVM2EVMOnRamp_forwardFromRouter is EVM2EVMOnRampSetup { // the proper revert point. This must be called by the owner. changePrank(OWNER); - Internal.PriceUpdates memory priceUpdates = getSinglePriceUpdateStruct(wrongToken, 1); + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(wrongToken, 1); s_priceRegistry.updatePrices(priceUpdates); // Change back to the router @@ -705,7 +705,7 @@ contract EVM2EVMOnRamp_getDataAvailabilityCostUSD is EVM2EVMOnRamp_getFeeSetup { uint256 dataAvailabilityLengthBytes = Internal.MESSAGE_FIXED_BYTES + 100 + - (5 * Internal.MESSAGE_BYTES_PER_TOKEN) + + (5 * Internal.MESSAGE_FIXED_BYTES_PER_TOKEN) + 50; uint256 dataAvailabilityGas = dynamicConfig.destDataAvailabilityOverheadGas + dynamicConfig.destGasPerDataAvailabilityByte * @@ -757,7 +757,7 @@ contract EVM2EVMOnRamp_getDataAvailabilityCostUSD is EVM2EVMOnRamp_getFeeSetup { uint256 dataAvailabilityLengthBytes = Internal.MESSAGE_FIXED_BYTES + messageDataLength + - (numberOfTokens * Internal.MESSAGE_BYTES_PER_TOKEN) + + (numberOfTokens * Internal.MESSAGE_FIXED_BYTES_PER_TOKEN) + tokenTransferBytesOverhead; uint256 dataAvailabilityGas = destDataAvailabilityOverheadGas + @@ -776,24 +776,21 @@ contract EVM2EVMOnRamp_getDataAvailabilityCostUSD is EVM2EVMOnRamp_getFeeSetup { contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { using USDPriceWith18Decimals for uint224; - function testNoTokenTransferChargesMinFeeSuccess() public { + function testNoTokenTransferChargesZeroFeeSuccess() public { Client.EVM2AnyMessage memory message = _generateEmptyMessage(); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); (uint256 feeAmount, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_feeTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); - assertEq(configUSDToValue(feeTokenConfig.minTokenTransferFeeUSD), feeAmount); + assertEq(0, feeAmount); assertEq(0, destGasOverhead); assertEq(0, destBytesOverhead); } function testSmallTokenTransferChargesMinFeeAndGasSuccess() public { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1000); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = s_onRamp.getTokenTransferFeeConfig( message.tokenAmounts[0].token ); @@ -801,18 +798,16 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { (uint256 feeAmount, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_feeTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); - assertEq(configUSDToValue(feeTokenConfig.minTokenTransferFeeUSD), feeAmount); + assertEq(configUSDToValue(transferFeeConfig.minFeeUSD), feeAmount); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); } function testZeroAmountTokenTransferChargesMinFeeAndAgasSuccess() public { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 0); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = s_onRamp.getTokenTransferFeeConfig( message.tokenAmounts[0].token ); @@ -820,18 +815,16 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { (uint256 feeAmount, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_feeTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); - assertEq(configUSDToValue(feeTokenConfig.minTokenTransferFeeUSD), feeAmount); + assertEq(configUSDToValue(transferFeeConfig.minFeeUSD), feeAmount); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); } function testLargeTokenTransferChargesMaxFeeAndGasSuccess() public { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1e36); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = s_onRamp.getTokenTransferFeeConfig( message.tokenAmounts[0].token ); @@ -839,11 +832,10 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { (uint256 feeAmount, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_feeTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); - assertEq(configUSDToValue(feeTokenConfig.maxTokenTransferFeeUSD), feeAmount); + assertEq(configUSDToValue(transferFeeConfig.maxFeeUSD), feeAmount); assertEq(transferFeeConfig.destGasOverhead, destGasOverhead); assertEq(transferFeeConfig.destBytesOverhead, destBytesOverhead); } @@ -852,7 +844,6 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { uint256 tokenAmount = 10000e18; Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, tokenAmount); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = s_onRamp.getTokenTransferFeeConfig( message.tokenAmounts[0].token ); @@ -860,8 +851,7 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { (uint256 feeAmount, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_feeTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); uint256 usdValue = calcUSDValueFromTokenAmount(s_feeTokenPrice, tokenAmount); @@ -873,7 +863,7 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { } function testWETHTokenBpsFeeSuccess() public { - uint256 tokenAmount = 10000e18; + uint256 tokenAmount = 100e18; Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ receiver: abi.encode(OWNER), @@ -884,7 +874,6 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { }); message.tokenAmounts[0] = Client.EVMTokenAmount({token: s_sourceRouter.getWrappedNative(), amount: tokenAmount}); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = s_onRamp.getTokenTransferFeeConfig( message.tokenAmounts[0].token ); @@ -892,8 +881,7 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { (uint256 feeAmount, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_wrappedTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); uint256 usdValue = calcUSDValueFromTokenAmount(s_wrappedTokenPrice, tokenAmount); @@ -916,7 +904,6 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { }); message.tokenAmounts[0] = Client.EVMTokenAmount({token: CUSTOM_TOKEN, amount: tokenAmount}); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); EVM2EVMOnRamp.TokenTransferFeeConfig memory transferFeeConfig = s_onRamp.getTokenTransferFeeConfig( message.tokenAmounts[0].token ); @@ -924,8 +911,7 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { (uint256 feeAmount, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_feeTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); uint256 usdValue = calcUSDValueFromTokenAmount(s_customTokenPrice, tokenAmount); @@ -941,6 +927,8 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { memory tokenTransferFeeConfigArgs = new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](1); tokenTransferFeeConfigArgs[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ token: s_sourceFeeToken, + minFeeUSD: 1, + maxFeeUSD: 0, ratio: 0, destGasOverhead: 0, destBytesOverhead: 0 @@ -948,16 +936,14 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { s_onRamp.setTokenTransferFeeConfig(tokenTransferFeeConfigArgs); Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1e36); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); (uint256 feeAmount, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_feeTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); // if token charges 0 bps, it should cost minFee to transfer - assertEq(configUSDToValue(feeTokenConfig.minTokenTransferFeeUSD), feeAmount); + assertEq(configUSDToValue(tokenTransferFeeConfigArgs[0].minFeeUSD), feeAmount); assertEq(0, destGasOverhead); assertEq(0, destBytesOverhead); } @@ -980,19 +966,16 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { single[0] = Client.EVMTokenAmount({token: s_sourceTokens[0], amount: amount * transfers}); address feeToken = s_sourceRouter.getWrappedNative(); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(feeToken); (uint256 feeSingle, uint32 gasOverheadSingle, uint32 bytesOverheadSingle) = s_onRamp.getTokenTransferCost( feeToken, s_wrappedTokenPrice, - single, - feeTokenConfig + single ); (uint256 feeMultiple, uint32 gasOverheadMultiple, uint32 bytesOverheadMultiple) = s_onRamp.getTokenTransferCost( feeToken, s_wrappedTokenPrice, - multiple, - feeTokenConfig + multiple ); // Note that there can be a rounding error once per split. @@ -1004,6 +987,11 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { function testMixedTokenTransferFeeSuccess() public { address[3] memory testTokens = [s_sourceFeeToken, s_sourceRouter.getWrappedNative(), CUSTOM_TOKEN]; uint224[3] memory tokenPrices = [s_feeTokenPrice, s_wrappedTokenPrice, s_customTokenPrice]; + EVM2EVMOnRamp.TokenTransferFeeConfig[3] memory tokenTransferFeeConfigs = [ + s_onRamp.getTokenTransferFeeConfig(testTokens[0]), + s_onRamp.getTokenTransferFeeConfig(testTokens[1]), + s_onRamp.getTokenTransferFeeConfig(testTokens[2]) + ]; Client.EVM2AnyMessage memory message = Client.EVM2AnyMessage({ receiver: abi.encode(OWNER), @@ -1012,7 +1000,6 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { feeToken: s_sourceRouter.getWrappedNative(), extraArgs: Client._argsToBytes(Client.EVMExtraArgsV1({gasLimit: GAS_LIMIT})) }); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); uint256 expectedTotalGas = 0; uint256 expectedTotalBytes = 0; @@ -1025,43 +1012,53 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { (uint256 feeAmount, uint32 destGasOverhead, uint32 destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_wrappedTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); - assertEq(configUSDToValue(feeTokenConfig.minTokenTransferFeeUSD), feeAmount); + + uint256 expectedFeeUSD = 0; + for (uint256 i = 0; i < testTokens.length; ++i) { + expectedFeeUSD += tokenTransferFeeConfigs[i].minFeeUSD; + } + + assertEq(configUSDToValue(expectedFeeUSD), feeAmount); assertEq(expectedTotalGas, destGasOverhead); assertEq(expectedTotalBytes, destBytesOverhead); - // Set 1st token transfer to a meaningful amount, total bps fee is now between min and max token transfer fees + // Set 1st token transfer to a meaningful amount so its bps fee is now between min and max fee message.tokenAmounts[0] = Client.EVMTokenAmount({token: testTokens[0], amount: 10000e18}); (feeAmount, destGasOverhead, destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_wrappedTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); - uint256 usdFeeValue; - for (uint256 i = 0; i < testTokens.length; ++i) { - usdFeeValue += applyBpsRatio( - calcUSDValueFromTokenAmount(tokenPrices[i], message.tokenAmounts[i].amount), - s_tokenTransferFeeConfigArgs[i].ratio - ); - } - assertEq(usdFeeValue, feeAmount); + expectedFeeUSD = applyBpsRatio( + calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), + tokenTransferFeeConfigs[0].ratio + ); + expectedFeeUSD += configUSDToValue(tokenTransferFeeConfigs[1].minFeeUSD); + expectedFeeUSD += configUSDToValue(tokenTransferFeeConfigs[2].minFeeUSD); + + assertEq(expectedFeeUSD, feeAmount); assertEq(expectedTotalGas, destGasOverhead); assertEq(expectedTotalBytes, destBytesOverhead); - // Set 2nd token transfer to a large amount, total bps fee is now higher than max token transfer fee + // Set 2nd token transfer to a large amount that is higher than maxFeeUSD message.tokenAmounts[1] = Client.EVMTokenAmount({token: testTokens[1], amount: 1e36}); (feeAmount, destGasOverhead, destBytesOverhead) = s_onRamp.getTokenTransferCost( message.feeToken, s_wrappedTokenPrice, - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); - assertEq(configUSDToValue(feeTokenConfig.maxTokenTransferFeeUSD), feeAmount); + expectedFeeUSD = applyBpsRatio( + calcUSDValueFromTokenAmount(tokenPrices[0], message.tokenAmounts[0].amount), + tokenTransferFeeConfigs[0].ratio + ); + expectedFeeUSD += configUSDToValue(tokenTransferFeeConfigs[1].maxFeeUSD); + expectedFeeUSD += configUSDToValue(tokenTransferFeeConfigs[2].minFeeUSD); + + assertEq(expectedFeeUSD, feeAmount); assertEq(expectedTotalGas, destGasOverhead); assertEq(expectedTotalBytes, destBytesOverhead); } @@ -1070,13 +1067,11 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { function testUnsupportedTokenReverts() public { address NOT_SUPPORTED_TOKEN = address(123); - Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(NOT_SUPPORTED_TOKEN, 200000e18); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); vm.expectRevert(abi.encodeWithSelector(EVM2EVMOnRamp.UnsupportedToken.selector, NOT_SUPPORTED_TOKEN)); - s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts, feeTokenConfig); + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); } function testValidatedPriceStalenessReverts() public { @@ -1084,7 +1079,6 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { Client.EVM2AnyMessage memory message = _generateSingleTokenMessage(s_sourceFeeToken, 1e36); message.tokenAmounts[0].token = s_sourceRouter.getWrappedNative(); - EVM2EVMOnRamp.FeeTokenConfig memory feeTokenConfig = s_onRamp.getFeeTokenConfig(message.feeToken); vm.expectRevert( abi.encodeWithSelector( @@ -1095,7 +1089,7 @@ contract EVM2EVMOnRamp_getTokenTransferCost is EVM2EVMOnRamp_getFeeSetup { ) ); - s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts, feeTokenConfig); + s_onRamp.getTokenTransferCost(message.feeToken, s_feeTokenPrice, message.tokenAmounts); } } @@ -1199,8 +1193,7 @@ contract EVM2EVMOnRamp_getFee is EVM2EVMOnRamp_getFeeSetup { (uint256 transferFeeUSD, , ) = s_onRamp.getTokenTransferCost( message.feeToken, feeTokenPrices[i], - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); uint256 messageFeeUSD = (transferFeeUSD * feeTokenConfig.premiumMultiplier); uint256 dataAvailabilityFeeUSD = s_onRamp.getDataAvailabilityCostUSD( @@ -1254,8 +1247,7 @@ contract EVM2EVMOnRamp_getFee is EVM2EVMOnRamp_getFeeSetup { (uint256 transferFeeUSD, , ) = s_onRamp.getTokenTransferCost( message.feeToken, feeTokenPrices[i], - message.tokenAmounts, - feeTokenConfig + message.tokenAmounts ); uint256 messageFeeUSD = (transferFeeUSD * feeTokenConfig.premiumMultiplier); uint256 dataAvailabilityFeeUSD = s_onRamp.getDataAvailabilityCostUSD( @@ -1543,17 +1535,21 @@ contract EVM2EVMOnRamp_setFeeTokenConfig is EVM2EVMOnRampSetup { contract EVM2EVMOnRamp_setTokenTransferFeeConfig is EVM2EVMOnRampSetup { event TokenTransferFeeConfigSet(EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] transferFeeConfig); - function testSetFeeTokenConfigSuccess() public { + function testSetTokenTransferFeeSuccess() public { EVM2EVMOnRamp.TokenTransferFeeConfigArgs[] memory tokenTransferFeeConfigArgs = new EVM2EVMOnRamp.TokenTransferFeeConfigArgs[](2); tokenTransferFeeConfigArgs[0] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ token: address(0), + minFeeUSD: 0, + maxFeeUSD: 0, ratio: 0, destGasOverhead: 0, destBytesOverhead: 0 }); tokenTransferFeeConfigArgs[1] = EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ token: address(1), + minFeeUSD: 1, + maxFeeUSD: 1, ratio: 1, destGasOverhead: 1, destBytesOverhead: 1 @@ -1567,6 +1563,8 @@ contract EVM2EVMOnRamp_setTokenTransferFeeConfig is EVM2EVMOnRampSetup { EVM2EVMOnRamp.TokenTransferFeeConfig memory tokenTransferFeeConfig0 = s_onRamp.getTokenTransferFeeConfig( address(0) ); + assertEq(0, tokenTransferFeeConfig0.minFeeUSD); + assertEq(0, tokenTransferFeeConfig0.maxFeeUSD); assertEq(0, tokenTransferFeeConfig0.ratio); assertEq(0, tokenTransferFeeConfig0.destGasOverhead); assertEq(0, tokenTransferFeeConfig0.destBytesOverhead); @@ -1574,6 +1572,8 @@ contract EVM2EVMOnRamp_setTokenTransferFeeConfig is EVM2EVMOnRampSetup { EVM2EVMOnRamp.TokenTransferFeeConfig memory tokenTransferFeeConfig1 = s_onRamp.getTokenTransferFeeConfig( address(1) ); + assertEq(1, tokenTransferFeeConfig1.minFeeUSD); + assertEq(1, tokenTransferFeeConfig1.maxFeeUSD); assertEq(1, tokenTransferFeeConfig1.ratio); assertEq(1, tokenTransferFeeConfig1.destGasOverhead); assertEq(1, tokenTransferFeeConfig1.destBytesOverhead); diff --git a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol index f4714f9230..6cf8d70ba3 100644 --- a/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol +++ b/contracts/src/v0.8/ccip/test/onRamp/EVM2EVMOnRampSetup.t.sol @@ -32,7 +32,7 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { TokenSetup.setUp(); PriceRegistrySetup.setUp(); - s_priceRegistry.updatePrices(getSinglePriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); + s_priceRegistry.updatePrices(getSingleTokenPriceUpdateStruct(CUSTOM_TOKEN, CUSTOM_TOKEN_PRICE)); address WETH = s_sourceRouter.getWrappedNative(); @@ -40,8 +40,6 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { EVM2EVMOnRamp.FeeTokenConfigArgs({ token: s_sourceFeeToken, networkFeeUSD: 1_00, // 1 USD - minTokenTransferFeeUSD: 1_00, // 1 USD - maxTokenTransferFeeUSD: 5000_00, // 5,000 USD gasMultiplier: 1e18, // 1x premiumMultiplier: 5e17, // 0.5x enabled: true @@ -51,8 +49,6 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { EVM2EVMOnRamp.FeeTokenConfigArgs({ token: WETH, networkFeeUSD: 5_00, // 5 USD - minTokenTransferFeeUSD: 2_00, // 2 USD - maxTokenTransferFeeUSD: 10000_00, // 10,000 USD gasMultiplier: 2e18, // 2x premiumMultiplier: 2e18, // 2x enabled: true @@ -62,6 +58,8 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { s_tokenTransferFeeConfigArgs.push( EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ token: s_sourceFeeToken, + minFeeUSD: 1_00, // 1 USD + maxFeeUSD: 1000_00, // 1,000 USD ratio: 2_5, // 2.5 bps, or 0.025% destGasOverhead: 40_000, destBytesOverhead: 0 @@ -70,6 +68,8 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { s_tokenTransferFeeConfigArgs.push( EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ token: s_sourceRouter.getWrappedNative(), + minFeeUSD: 50, // 0.5 USD + maxFeeUSD: 500_00, // 500 USD ratio: 5_0, // 5 bps, or 0.05% destGasOverhead: 10_000, destBytesOverhead: 100 @@ -78,6 +78,8 @@ contract EVM2EVMOnRampSetup is TokenSetup, PriceRegistrySetup { s_tokenTransferFeeConfigArgs.push( EVM2EVMOnRamp.TokenTransferFeeConfigArgs({ token: CUSTOM_TOKEN, + minFeeUSD: 2_00, // 1 USD + maxFeeUSD: 2000_00, // 1,000 USD ratio: 10_0, // 10 bps, or 0.1% destGasOverhead: 1, destBytesOverhead: 200 diff --git a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol index 995bf3e6e6..2fdb7d7835 100644 --- a/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol +++ b/contracts/src/v0.8/ccip/test/priceRegistry/PriceRegistry.t.sol @@ -69,8 +69,7 @@ contract PriceRegistrySetup is TokenSetup, RouterSetup { } Internal.PriceUpdates memory priceUpdates = getPriceUpdatesStruct(pricedTokens, tokenPrices); - priceUpdates.destChainSelector = DEST_CHAIN_ID; - priceUpdates.usdPerUnitGas = PACKED_USD_PER_GAS; + priceUpdates.gasPriceUpdates = getSingleGasPriceUpdateStruct(DEST_CHAIN_ID, PACKED_USD_PER_GAS).gasPriceUpdates; s_encodedInitialPriceUpdates = abi.encode(priceUpdates); address[] memory priceUpdaters = new address[](0); @@ -229,35 +228,104 @@ contract PriceRegistry_applyFeeTokensUpdates is PriceRegistrySetup { } contract PriceRegistry_updatePrices is PriceRegistrySetup { - // Cheat to store the price updates in storage since struct arrays aren't supported. - bytes internal s_encodedNewPriceUpdates; + event UsdPerTokenUpdated(address indexed token, uint256 value, uint256 timestamp); + event UsdPerUnitGasUpdated(uint64 indexed destChain, uint256 value, uint256 timestamp); - function setUp() public virtual override { - PriceRegistrySetup.setUp(); - Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](2); + function testOnlyTokenPriceSuccess() public { + Internal.PriceUpdates memory update = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](1), + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + update.tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); + + vm.expectEmit(); + emit UsdPerTokenUpdated( + update.tokenPriceUpdates[0].sourceToken, + update.tokenPriceUpdates[0].usdPerToken, + block.timestamp + ); + + s_priceRegistry.updatePrices(update); + + assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, update.tokenPriceUpdates[0].usdPerToken); + } + + function testOnlyGasPriceSuccess() public { + Internal.PriceUpdates memory update = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: new Internal.GasPriceUpdate[](1) + }); + update.gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: 2000e18}); + + vm.expectEmit(); + emit UsdPerUnitGasUpdated( + update.gasPriceUpdates[0].destChainSelector, + update.gasPriceUpdates[0].usdPerUnitGas, + block.timestamp + ); + + s_priceRegistry.updatePrices(update); + + assertEq(s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_ID).value, update.gasPriceUpdates[0].usdPerUnitGas); + } + + function testUpdateMultiplePricesSuccess() public { + Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](3); tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); tokenPriceUpdates[1] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[1], usdPerToken: 1800e18}); - Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates[2] = Internal.TokenPriceUpdate({sourceToken: address(12345), usdPerToken: 1e18}); + + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](3); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: 2e6}); + gasPriceUpdates[1] = Internal.GasPriceUpdate({destChainSelector: SOURCE_CHAIN_ID, usdPerUnitGas: 2000e18}); + gasPriceUpdates[2] = Internal.GasPriceUpdate({destChainSelector: 12345, usdPerUnitGas: 1e18}); + + Internal.PriceUpdates memory update = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: DEST_CHAIN_ID, - usdPerUnitGas: 2e6 + gasPriceUpdates: gasPriceUpdates }); - s_encodedNewPriceUpdates = abi.encode(priceUpdates); - } - function testUpdatePricesSuccess() public { - Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedNewPriceUpdates, (Internal.PriceUpdates)); - s_priceRegistry.updatePrices(priceUpdates); + for (uint256 i = 0; i < tokenPriceUpdates.length; ++i) { + vm.expectEmit(); + emit UsdPerTokenUpdated( + update.tokenPriceUpdates[i].sourceToken, + update.tokenPriceUpdates[i].usdPerToken, + block.timestamp + ); + } + for (uint256 i = 0; i < gasPriceUpdates.length; ++i) { + vm.expectEmit(); + emit UsdPerUnitGasUpdated( + update.gasPriceUpdates[i].destChainSelector, + update.gasPriceUpdates[i].usdPerUnitGas, + block.timestamp + ); + } - assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[0]).value, priceUpdates.tokenPriceUpdates[0].usdPerToken); - assertEq(s_priceRegistry.getTokenPrice(s_sourceTokens[1]).value, priceUpdates.tokenPriceUpdates[1].usdPerToken); - assertEq(s_priceRegistry.getDestinationChainGasPrice(DEST_CHAIN_ID).value, priceUpdates.usdPerUnitGas); + s_priceRegistry.updatePrices(update); + + for (uint256 i = 0; i < tokenPriceUpdates.length; ++i) { + assertEq( + s_priceRegistry.getTokenPrice(update.tokenPriceUpdates[i].sourceToken).value, + tokenPriceUpdates[i].usdPerToken + ); + } + for (uint256 i = 0; i < gasPriceUpdates.length; ++i) { + assertEq( + s_priceRegistry.getDestinationChainGasPrice(update.gasPriceUpdates[i].destChainSelector).value, + gasPriceUpdates[i].usdPerUnitGas + ); + } } // Reverts function testOnlyCallableByUpdaterOrOwnerReverts() public { - Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedNewPriceUpdates, (Internal.PriceUpdates)); + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ + tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), + gasPriceUpdates: new Internal.GasPriceUpdate[](0) + }); + changePrank(STRANGER); vm.expectRevert(abi.encodeWithSelector(PriceRegistry.OnlyCallableByUpdaterOrOwner.selector)); s_priceRegistry.updatePrices(priceUpdates); @@ -297,10 +365,13 @@ contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { Internal.TokenPriceUpdate[] memory tokenPriceUpdates = new Internal.TokenPriceUpdate[](2); tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: feeToken, usdPerToken: usdPerFeeToken}); tokenPriceUpdates[1] = Internal.TokenPriceUpdate({sourceToken: linkToken, usdPerToken: usdPerLinkToken}); + + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: usdPerUnitGas}); + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: DEST_CHAIN_ID, - usdPerUnitGas: usdPerUnitGas + gasPriceUpdates: gasPriceUpdates }); s_priceRegistry.updatePrices(priceUpdates); @@ -318,8 +389,7 @@ contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_sourceTokens[0], usdPerToken: 4e18}); Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); s_priceRegistry.updatePrices(priceUpdates); @@ -349,8 +419,7 @@ contract PriceRegistry_convertTokenAmount is PriceRegistrySetup { tokenPriceUpdates[0] = Internal.TokenPriceUpdate({sourceToken: s_weth, usdPerToken: 18e17}); Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: tokenPriceUpdates, - destChainSelector: 0, - usdPerUnitGas: 0 + gasPriceUpdates: new Internal.GasPriceUpdate[](0) }); s_priceRegistry.updatePrices(priceUpdates); @@ -373,21 +442,23 @@ contract PriceRegistry_getTokenAndGasPrices is PriceRegistrySetup { Internal.PriceUpdates memory priceUpdates = abi.decode(s_encodedInitialPriceUpdates, (Internal.PriceUpdates)); assertEq(feeTokenPrice, s_sourceTokenPrices[0]); - assertEq(gasPrice, priceUpdates.usdPerUnitGas); + assertEq(gasPrice, priceUpdates.gasPriceUpdates[0].usdPerUnitGas); } function testZeroGasPriceSuccess() public { uint64 zeroGasDestChainSelector = 345678; + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: zeroGasDestChainSelector, usdPerUnitGas: 0}); + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), - destChainSelector: zeroGasDestChainSelector, - usdPerUnitGas: 0 + gasPriceUpdates: gasPriceUpdates }); s_priceRegistry.updatePrices(priceUpdates); (, uint224 gasPrice) = s_priceRegistry.getTokenAndGasPrices(s_sourceFeeToken, zeroGasDestChainSelector); - assertEq(gasPrice, priceUpdates.usdPerUnitGas); + assertEq(gasPrice, priceUpdates.gasPriceUpdates[0].usdPerUnitGas); } function testUnsupportedChainReverts() public { @@ -406,10 +477,12 @@ contract PriceRegistry_getTokenAndGasPrices is PriceRegistrySetup { uint256 diff = TWELVE_HOURS + 1; vm.warp(block.timestamp + diff); + Internal.GasPriceUpdate[] memory gasPriceUpdates = new Internal.GasPriceUpdate[](1); + gasPriceUpdates[0] = Internal.GasPriceUpdate({destChainSelector: DEST_CHAIN_ID, usdPerUnitGas: PACKED_USD_PER_GAS}); + Internal.PriceUpdates memory priceUpdates = Internal.PriceUpdates({ tokenPriceUpdates: new Internal.TokenPriceUpdate[](0), - destChainSelector: DEST_CHAIN_ID, - usdPerUnitGas: PACKED_USD_PER_GAS + gasPriceUpdates: gasPriceUpdates }); s_priceRegistry.updatePrices(priceUpdates); diff --git a/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol index cf7f59617a..dd5c0daebd 100644 --- a/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol +++ b/contracts/src/v0.8/ccip/test/rateLimiter/AggregateRateLimiter.t.sol @@ -22,7 +22,7 @@ contract AggregateTokenLimiterSetup is BaseTest, PriceRegistrySetup { BaseTest.setUp(); PriceRegistrySetup.setUp(); - Internal.PriceUpdates memory priceUpdates = getSinglePriceUpdateStruct(TOKEN, TOKEN_PRICE); + Internal.PriceUpdates memory priceUpdates = getSingleTokenPriceUpdateStruct(TOKEN, TOKEN_PRICE); s_priceRegistry.updatePrices(priceUpdates); s_config = RateLimiter.Config({isEnabled: true, rate: 5, capacity: 100}); diff --git a/contracts/src/v0.8/ccip/test/router/Router.t.sol b/contracts/src/v0.8/ccip/test/router/Router.t.sol index b580d9c4a9..11559cd0c2 100644 --- a/contracts/src/v0.8/ccip/test/router/Router.t.sol +++ b/contracts/src/v0.8/ccip/test/router/Router.t.sol @@ -199,8 +199,6 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { feeTokenConfigArgs[0] = EVM2EVMOnRamp.FeeTokenConfigArgs({ token: s_sourceTokens[1], networkFeeUSD: 1, - minTokenTransferFeeUSD: 1, - maxTokenTransferFeeUSD: 5, gasMultiplier: 108e16, premiumMultiplier: 1e18, enabled: true @@ -264,10 +262,12 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { s_priceRegistry.applyFeeTokensUpdates(feeTokens, new address[](0)); // Update the price of the newly set feeToken - Internal.PriceUpdates memory priceUpdates = getSinglePriceUpdateStruct(feeTokenWithZeroFeeAndGas, 2_000 ether); - priceUpdates.destChainSelector = DEST_CHAIN_ID; - priceUpdates.usdPerUnitGas = 0; - + Internal.PriceUpdates memory priceUpdates = getSingleTokenAndGasPriceUpdateStruct( + feeTokenWithZeroFeeAndGas, + 2_000 ether, + DEST_CHAIN_ID, + 0 + ); s_priceRegistry.updatePrices(priceUpdates); // Set the feeToken args on the onRamp @@ -275,8 +275,6 @@ contract Router_ccipSend is EVM2EVMOnRampSetup { feeTokenConfigArgs[0] = EVM2EVMOnRamp.FeeTokenConfigArgs({ token: s_sourceTokens[1], networkFeeUSD: 0, - minTokenTransferFeeUSD: 0, - maxTokenTransferFeeUSD: 5, gasMultiplier: 108e16, premiumMultiplier: 1e18, enabled: true diff --git a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol index ea37fb8387..0608340e67 100644 --- a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol +++ b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2Plus.sol @@ -2,19 +2,11 @@ pragma solidity ^0.8.0; import "../vrf/libraries/VRFV2PlusClient.sol"; +import "./IVRFSubscriptionV2Plus.sol"; -// Interface for initial version of VRFCoordinatorV2Plus -// Functions in this interface may not be supported when VRFCoordinatorV2Plus is upgraded to a new version -// TODO: Revisit these functions and decide which functions need to be backwards compatible -interface IVRFCoordinatorV2Plus { - /** - * @notice Get configuration relevant for making requests - * @return minimumRequestConfirmations global min for request confirmations - * @return maxGasLimit global max for request gas limit - * @return s_provingKeyHashes list of registered key hashes - */ - function getRequestConfig() external view returns (uint16, uint32, bytes32[] memory); - +// Interface that enables consumers of VRFCoordinatorV2Plus to be future-proof for upgrades +// This interface is supported by subsequent versions of VRFCoordinatorV2Plus +interface IVRFCoordinatorV2Plus is IVRFSubscriptionV2Plus { /** * @notice Request a set of random words. * @param req - a struct containing following fiels for randomness request: @@ -23,7 +15,7 @@ interface IVRFCoordinatorV2Plus { * ceilings, so you can select a specific one to bound your maximum per request cost. * subId - The ID of the VRF subscription. Must be funded * with the minimum subscription balance required for the selected keyHash. - * minimumRequestConfirmations - How many blocks you'd like the + * requestConfirmations - How many blocks you'd like the * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS * for why you may want to request more. The acceptable range is * [minimumRequestBlockConfirmations, 200]. @@ -41,75 +33,4 @@ interface IVRFCoordinatorV2Plus { * a request to a response in fulfillRandomWords. */ function requestRandomWords(VRFV2PlusClient.RandomWordsRequest calldata req) external returns (uint256 requestId); - - /** - * @notice Create a VRF subscription. - * @return subId - 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(COORDINATOR), - * @dev amount, - * @dev abi.encode(subId)); - */ - function createSubscription() external returns (uint256 subId); - - /** - * @notice Get a VRF subscription. - * @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 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); - - /** - * @notice Request subscription owner transfer. - * @param subId - ID of the subscription - * @param newOwner - proposed new owner of the subscription - */ - function requestSubscriptionOwnerTransfer(uint256 subId, address newOwner) external; - - /** - * @notice Request subscription owner transfer. - * @param subId - ID of the subscription - * @dev will revert if original owner of subId has - * not requested that msg.sender become the new owner. - */ - function acceptSubscriptionOwnerTransfer(uint256 subId) external; - - /** - * @notice Add a consumer to a VRF subscription. - * @param subId - ID of the subscription - * @param consumer - New consumer which can use the subscription - */ - function addConsumer(uint256 subId, address consumer) external; - - /** - * @notice Remove a consumer from a VRF subscription. - * @param subId - ID of the subscription - * @param consumer - Consumer to remove from the subscription - */ - function removeConsumer(uint256 subId, address consumer) external; - - /** - * @notice Cancel a subscription - * @param subId - ID of the subscription - * @param to - Where to send the remaining LINK to - */ - function cancelSubscription(uint256 subId, address to) external; - - /* - * @notice Check to see if there exists a request commitment consumers - * for all consumers and keyhashes for a given sub. - * @param subId - ID of the subscription - * @return true if there exists at least one unfulfilled request for the subscription, false - * otherwise. - */ - function pendingRequestExists(uint256 subId) external view returns (bool); - - function fundSubscriptionWithEth(uint256 subId) external payable; } diff --git a/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2PlusInternal.sol b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2PlusInternal.sol new file mode 100644 index 0000000000..9892b88e69 --- /dev/null +++ b/contracts/src/v0.8/dev/interfaces/IVRFCoordinatorV2PlusInternal.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; +import "./IVRFCoordinatorV2Plus.sol"; + +// IVRFCoordinatorV2PlusInternal is the interface used by chainlink core and should +// not be used by consumer conracts +// Future versions of VRF V2plus must conform to this interface +// VRF coordinator doesn't directly inherit from this interface because solidity +// imposes interface methods be external, whereas methods implementated VRF coordinator +// are public. This is OK because IVRFCoordinatorV2PlusInternal doesn't have any solidity +// use case. It is only used to generate gethwrappers +interface IVRFCoordinatorV2PlusInternal is IVRFCoordinatorV2Plus { + event RandomWordsRequested( + bytes32 indexed keyHash, + uint256 requestId, + uint256 preSeed, + uint256 indexed subId, + uint16 minimumRequestConfirmations, + uint32 callbackGasLimit, + uint32 numWords, + bytes extraArgs, + address indexed sender + ); + + event RandomWordsFulfilled( + uint256 indexed requestId, + uint256 outputSeed, + uint256 indexed subId, + uint96 payment, + bool success + ); + + struct RequestCommitment { + uint64 blockNum; + uint256 subId; + uint32 callbackGasLimit; + uint32 numWords; + address sender; + bytes extraArgs; + } + + struct Proof { + uint256[2] pk; + uint256[2] gamma; + uint256 c; + uint256 s; + uint256 seed; + address uWitness; + uint256[2] cGammaWitness; + uint256[2] sHashWitness; + uint256 zInv; + } + + function s_requestCommitments(uint256 requestID) external view returns (bytes32); + + function fulfillRandomWords(Proof memory proof, RequestCommitment memory rc) external returns (uint96); + + function LINK_NATIVE_FEED() external view returns (address); +} diff --git a/contracts/src/v0.8/dev/interfaces/IVRFMigratableCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/interfaces/IVRFMigratableCoordinatorV2Plus.sol deleted file mode 100644 index 687ff9790f..0000000000 --- a/contracts/src/v0.8/dev/interfaces/IVRFMigratableCoordinatorV2Plus.sol +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.4; - -import "../vrf/libraries/VRFV2PlusClient.sol"; - -// Interface that enables consumers of VRFCoordinatorV2Plus to be future-proof for upgrades -// This interface is supported by subsequent versions of VRFCoordinatorV2Plus -interface IVRFMigratableCoordinatorV2Plus { - /** - * @notice Request a set of random words. - * @param req - a struct containing following fiels for randomness request: - * keyHash - Corresponds to a particular oracle job which uses - * that key for generating the VRF proof. Different keyHash's have different gas price - * ceilings, so you can select a specific one to bound your maximum per request cost. - * subId - The ID of the VRF subscription. Must be funded - * with the minimum subscription balance required for the selected keyHash. - * minimumRequestConfirmations - How many blocks you'd like the - * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS - * for why you may want to request more. The acceptable range is - * [minimumRequestBlockConfirmations, 200]. - * callbackGasLimit - How much gas you'd like to receive in your - * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords - * may be slightly less than this amount because of gas used calling the function - * (argument decoding etc.), so you may need to request slightly more than you expect - * to have inside fulfillRandomWords. The acceptable range is - * [0, maxGasLimit] - * 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. - * @return requestId - A unique identifier of the request. Can be used to match - * a request to a response in fulfillRandomWords. - */ - function requestRandomWords(VRFV2PlusClient.RandomWordsRequest calldata req) external returns (uint256 requestId); -} diff --git a/contracts/src/v0.8/dev/interfaces/IVRFSubscriptionV2Plus.sol b/contracts/src/v0.8/dev/interfaces/IVRFSubscriptionV2Plus.sol index 47b31d98bd..49c131988a 100644 --- a/contracts/src/v0.8/dev/interfaces/IVRFSubscriptionV2Plus.sol +++ b/contracts/src/v0.8/dev/interfaces/IVRFSubscriptionV2Plus.sol @@ -49,9 +49,9 @@ interface IVRFSubscriptionV2Plus { * @dev address(COORDINATOR), * @dev amount, * @dev abi.encode(subId)); - * @dev Note to fund the subscription with ETH, use fundSubscriptionWithEth. Be sure - * @dev to send ETH with the call, for example: - * @dev COORDINATOR.fundSubscriptionWithEth{value: amount}(subId); + * @dev Note to fund the subscription with Native, use fundSubscriptionWithNative. Be sure + * @dev to send Native with the call, for example: + * @dev COORDINATOR.fundSubscriptionWithNative{value: amount}(subId); */ function createSubscription() external returns (uint256 subId); @@ -59,7 +59,7 @@ interface IVRFSubscriptionV2Plus { * @notice Get a VRF subscription. * @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 nativeBalance - native 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. @@ -69,7 +69,16 @@ interface IVRFSubscriptionV2Plus { ) external view - returns (uint96 balance, uint96 ethBalance, uint64 reqCount, address owner, address[] memory consumers); + returns (uint96 balance, uint96 nativeBalance, uint64 reqCount, address owner, address[] memory consumers); + + /* + * @notice Check to see if there exists a request commitment consumers + * for all consumers and keyhashes for a given sub. + * @param subId - ID of the subscription + * @return true if there exists at least one unfulfilled request for the subscription, false + * otherwise. + */ + function pendingRequestExists(uint256 subId) external view returns (bool); /** * @notice Paginate through all active VRF subscriptions. @@ -81,9 +90,9 @@ interface IVRFSubscriptionV2Plus { function getActiveSubscriptionIds(uint256 startIndex, uint256 maxCount) external view returns (uint256[] memory); /** - * @notice Fund a subscription with ETH. + * @notice Fund a subscription with native. * @param subId - ID of the subscription * @notice This method expects msg.value to be greater than 0. */ - function fundSubscriptionWithEth(uint256 subId) external payable; + function fundSubscriptionWithNative(uint256 subId) external payable; } diff --git a/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol b/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol index 9e3181978f..c4781cbde8 100644 --- a/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol +++ b/contracts/src/v0.8/dev/vrf/SubscriptionAPI.sol @@ -14,7 +14,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr /// @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; + AggregatorV3Interface public LINK_NATIVE_FEED; // We need to maintain a list of consuming addresses. // This bound ensures we are able to loop over them as needed. @@ -31,9 +31,9 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr error MustBeRequestedOwner(address proposedOwner); error BalanceInvariantViolated(uint256 internalBalance, uint256 externalBalance); // Should never happen event FundsRecovered(address to, uint256 amount); - event EthFundsRecovered(address to, uint256 amount); + event NativeFundsRecovered(address to, uint256 amount); error LinkAlreadySet(); - error FailedToSendEther(); + error FailedToSendNative(); error FailedToTransferLink(); error IndexOutOfRange(); error LinkNotSet(); @@ -45,7 +45,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr uint96 balance; // Common link balance used for all consumer requests. // 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. + uint96 nativeBalance; // Common native balance used for all consumer requests. uint64 reqCount; } // We use the config for the mgmt APIs @@ -64,7 +64,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr mapping(address => mapping(uint256 => uint64)) /* consumer */ /* subId */ /* nonce */ internal s_consumers; mapping(uint256 => SubscriptionConfig) /* subId */ /* subscriptionConfig */ internal s_subscriptionConfigs; mapping(uint256 => Subscription) /* subId */ /* subscription */ internal s_subscriptions; - // subscription nonce used to construct subID. Rises monotonically + // 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 @@ -78,20 +78,20 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr // A discrepancy with this contract's link balance indicates someone // sent tokens using transfer and so we may need to use recoverFunds. uint96 public s_totalBalance; - // s_totalEthBalance tracks the total eth sent to/from - // this contract through fundSubscription, cancelSubscription and oracleWithdrawEth. - // A discrepancy with this contract's eth balance indicates someone - // sent eth using transfer and so we may need to use recoverEthFunds. - uint96 public s_totalEthBalance; + // s_totalNativeBalance tracks the total native sent to/from + // this contract through fundSubscription, cancelSubscription and oracleWithdrawNative. + // A discrepancy with this contract's native balance indicates someone + // sent native using transfer and so we may need to use recoverNativeFunds. + uint96 public s_totalNativeBalance; mapping(address => uint96) /* oracle */ /* LINK balance */ internal s_withdrawableTokens; - mapping(address => uint96) /* oracle */ /* ETH balance */ internal s_withdrawableEth; + mapping(address => uint96) /* oracle */ /* native balance */ internal s_withdrawableNative; event SubscriptionCreated(uint256 indexed subId, address owner); event SubscriptionFunded(uint256 indexed subId, uint256 oldBalance, uint256 newBalance); - event SubscriptionFundedWithEth(uint256 indexed subId, uint256 oldEthBalance, uint256 newEthBalance); + event SubscriptionFundedWithNative(uint256 indexed subId, uint256 oldNativeBalance, uint256 newNativeBalance); event SubscriptionConsumerAdded(uint256 indexed subId, address consumer); event SubscriptionConsumerRemoved(uint256 indexed subId, address consumer); - event SubscriptionCanceled(uint256 indexed subId, address to, uint256 amountLink, uint256 amountEth); + event SubscriptionCanceled(uint256 indexed subId, address to, uint256 amountLink, uint256 amountNative); event SubscriptionOwnerTransferRequested(uint256 indexed subId, address from, address to); event SubscriptionOwnerTransferred(uint256 indexed subId, address from, address to); @@ -128,18 +128,18 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr constructor() ConfirmedOwner(msg.sender) {} /** - * @notice set the LINK token contract and link eth feed to be + * @notice set the LINK token contract and link native feed to be * used by this coordinator * @param link - address of link token - * @param linkEthFeed address of the link eth feed + * @param linkNativeFeed address of the link native feed */ - function setLINKAndLINKETHFeed(address link, address linkEthFeed) external onlyOwner { + function setLINKAndLINKNativeFeed(address link, address linkNativeFeed) 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); + LINK_NATIVE_FEED = AggregatorV3Interface(linkNativeFeed); } /** @@ -183,12 +183,12 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr } /** - * @notice Recover eth sent with transfer/call/send instead of fundSubscription. - * @param to address to send eth to + * @notice Recover native sent with transfer/call/send instead of fundSubscription. + * @param to address to send native to */ - function recoverEthFunds(address payable to) external onlyOwner { + function recoverNativeFunds(address payable to) external onlyOwner { uint256 externalBalance = address(this).balance; - uint256 internalBalance = uint256(s_totalEthBalance); + uint256 internalBalance = uint256(s_totalNativeBalance); if (internalBalance > externalBalance) { revert BalanceInvariantViolated(internalBalance, externalBalance); } @@ -196,9 +196,9 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr uint256 amount = externalBalance - internalBalance; (bool sent, ) = to.call{value: amount}(""); if (!sent) { - revert FailedToSendEther(); + revert FailedToSendNative(); } - emit EthFundsRecovered(to, amount); + emit NativeFundsRecovered(to, amount); } // If the balances are equal, nothing to be done. } @@ -223,20 +223,20 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr } /* - * @notice Oracle withdraw ETH earned through fulfilling requests + * @notice Oracle withdraw native earned through fulfilling requests * @param recipient where to send the funds * @param amount amount to withdraw */ - function oracleWithdrawEth(address payable recipient, uint96 amount) external nonReentrant { - if (s_withdrawableEth[msg.sender] < amount) { + function oracleWithdrawNative(address payable recipient, uint96 amount) external nonReentrant { + if (s_withdrawableNative[msg.sender] < amount) { revert InsufficientBalance(); } // Prevent re-entrancy by updating state before transfer. - s_withdrawableEth[msg.sender] -= amount; - s_totalEthBalance -= amount; + s_withdrawableNative[msg.sender] -= amount; + s_totalNativeBalance -= amount; (bool sent, ) = recipient.call{value: amount}(""); if (!sent) { - revert FailedToSendEther(); + revert FailedToSendNative(); } } @@ -262,7 +262,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr /** * @inheritdoc IVRFSubscriptionV2Plus */ - function fundSubscriptionWithEth(uint256 subId) external payable override nonReentrant { + function fundSubscriptionWithNative(uint256 subId) external payable override nonReentrant { if (s_subscriptionConfigs[subId].owner == address(0)) { revert InvalidSubscription(); } @@ -270,10 +270,10 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr // anyone can fund a subscription. // We also do not check that msg.value > 0, since that's just a no-op // and would be a waste of gas on the caller's part. - uint256 oldEthBalance = s_subscriptions[subId].ethBalance; - s_subscriptions[subId].ethBalance += uint96(msg.value); - s_totalEthBalance += uint96(msg.value); - emit SubscriptionFundedWithEth(subId, oldEthBalance, oldEthBalance + msg.value); + uint256 oldNativeBalance = s_subscriptions[subId].nativeBalance; + s_subscriptions[subId].nativeBalance += uint96(msg.value); + s_totalNativeBalance += uint96(msg.value); + emit SubscriptionFundedWithNative(subId, oldNativeBalance, oldNativeBalance + msg.value); } /** @@ -285,14 +285,14 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr public view override - returns (uint96 balance, uint96 ethBalance, uint64 reqCount, address owner, address[] memory consumers) + returns (uint96 balance, uint96 nativeBalance, 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].nativeBalance, s_subscriptions[subId].reqCount, s_subscriptionConfigs[subId].owner, s_subscriptionConfigs[subId].consumers @@ -329,7 +329,7 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr s_currentSubNonce++; // Initialize storage variables. address[] memory consumers = new address[](0); - s_subscriptions[subId] = Subscription({balance: 0, ethBalance: 0, reqCount: 0}); + s_subscriptions[subId] = Subscription({balance: 0, nativeBalance: 0, reqCount: 0}); s_subscriptionConfigs[subId] = SubscriptionConfig({ owner: msg.sender, requestedOwner: address(0), @@ -392,11 +392,11 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr emit SubscriptionConsumerAdded(subId, consumer); } - function deleteSubscription(uint256 subId) internal returns (uint96 balance, uint96 ethBalance) { + function deleteSubscription(uint256 subId) internal returns (uint96 balance, uint96 nativeBalance) { SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId]; Subscription memory sub = s_subscriptions[subId]; balance = sub.balance; - ethBalance = sub.ethBalance; + nativeBalance = sub.nativeBalance; // Note bounded by MAX_CONSUMERS; // If no consumers, does nothing. for (uint256 i = 0; i < subConfig.consumers.length; i++) { @@ -406,12 +406,12 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr delete s_subscriptions[subId]; s_subIds.remove(subId); s_totalBalance -= balance; - s_totalEthBalance -= ethBalance; - return (balance, ethBalance); + s_totalNativeBalance -= nativeBalance; + return (balance, nativeBalance); } function cancelSubscriptionHelper(uint256 subId, address to) internal { - (uint96 balance, uint96 ethBalance) = deleteSubscription(subId); + (uint96 balance, uint96 nativeBalance) = deleteSubscription(subId); // Only withdraw LINK if the token is active and there is a balance. if (address(LINK) != address(0) && balance != 0) { @@ -420,12 +420,12 @@ abstract contract SubscriptionAPI is ConfirmedOwner, IERC677Receiver, IVRFSubscr } } - // send eth to the "to" address using call - (bool success, ) = to.call{value: uint256(ethBalance)}(""); + // send native to the "to" address using call + (bool success, ) = to.call{value: uint256(nativeBalance)}(""); if (!success) { - revert FailedToSendEther(); + revert FailedToSendNative(); } - emit SubscriptionCanceled(subId, to, balance, ethBalance); + emit SubscriptionCanceled(subId, to, balance, nativeBalance); } modifier onlySubOwner(uint256 subId) { diff --git a/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol b/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol index 5220f1c151..0e6e2b2201 100644 --- a/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/VRFConsumerBaseV2Plus.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.4; -import "../interfaces/IVRFMigratableCoordinatorV2Plus.sol"; +import "../interfaces/IVRFCoordinatorV2Plus.sol"; import "../interfaces/IVRFMigratableConsumerV2Plus.sol"; import "../../shared/access/ConfirmedOwner.sol"; @@ -103,13 +103,13 @@ abstract contract VRFConsumerBaseV2Plus is IVRFMigratableConsumerV2Plus, Confirm error OnlyOwnerOrCoordinator(address have, address owner, address coordinator); error ZeroAddress(); - IVRFMigratableCoordinatorV2Plus public s_vrfCoordinator; + IVRFCoordinatorV2Plus public s_vrfCoordinator; /** * @param _vrfCoordinator address of VRFCoordinator contract */ constructor(address _vrfCoordinator) ConfirmedOwner(msg.sender) { - s_vrfCoordinator = IVRFMigratableCoordinatorV2Plus(_vrfCoordinator); + s_vrfCoordinator = IVRFCoordinatorV2Plus(_vrfCoordinator); } /** @@ -142,7 +142,7 @@ abstract contract VRFConsumerBaseV2Plus is IVRFMigratableConsumerV2Plus, Confirm * @inheritdoc IVRFMigratableConsumerV2Plus */ function setCoordinator(address _vrfCoordinator) public override onlyOwnerOrCoordinator { - s_vrfCoordinator = IVRFMigratableCoordinatorV2Plus(_vrfCoordinator); + s_vrfCoordinator = IVRFCoordinatorV2Plus(_vrfCoordinator); } modifier onlyOwnerOrCoordinator() { diff --git a/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol similarity index 93% rename from contracts/src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol rename to contracts/src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol index 50abefc3ff..113f098614 100644 --- a/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol @@ -10,8 +10,9 @@ import "../../ChainSpecificUtil.sol"; import "./SubscriptionAPI.sol"; import "./libraries/VRFV2PlusClient.sol"; import "../interfaces/IVRFCoordinatorV2PlusMigration.sol"; +import "../interfaces/IVRFCoordinatorV2Plus.sol"; -contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { +contract VRFCoordinatorV2_5 is VRF, SubscriptionAPI, IVRFCoordinatorV2Plus { /// @dev should always be available BlockhashStoreInterface public immutable BLOCKHASH_STORE; @@ -58,10 +59,11 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { bytes extraArgs, address indexed sender ); + event RandomWordsFulfilled( uint256 indexed requestId, uint256 outputSeed, - uint256 indexed subID, + uint256 indexed subId, uint96 payment, bool success ); @@ -73,9 +75,9 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { // Flat fee charged per fulfillment in millionths of link // So fee range is [0, 2^32/10^6]. uint32 fulfillmentFlatFeeLinkPPM; - // Flat fee charged per fulfillment in millionths of eth. + // Flat fee charged per fulfillment in millionths of native. // So fee range is [0, 2^32/10^6]. - uint32 fulfillmentFlatFeeEthPPM; + uint32 fulfillmentFlatFeeNativePPM; } event ConfigSet( uint16 minimumRequestConfirmations, @@ -139,9 +141,9 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { * @notice Sets the configuration of the vrfv2 coordinator * @param minimumRequestConfirmations global min for request confirmations * @param maxGasLimit global max for request gas limit - * @param stalenessSeconds if the eth/link feed is more stale then this, use the fallback price + * @param stalenessSeconds if the native/link feed is more stale then this, use the fallback price * @param gasAfterPaymentCalculation gas used in doing accounting after completing the gas measurement - * @param fallbackWeiPerUnitLink fallback eth/link price in the case of a stale feed + * @param fallbackWeiPerUnitLink fallback native/link price in the case of a stale feed * @param feeConfig fee configuration */ function setConfig( @@ -224,11 +226,13 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { * 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. * extraArgs - Encoded extra arguments that has a boolean flag for whether payment - * should be made in ETH or LINK. Payment in LINK is only available if the LINK token is available to this contract. + * should be made in native or LINK. Payment in LINK is only available if the LINK token is available to this contract. * @return requestId - A unique identifier of the request. Can be used to match * a request to a response in fulfillRandomWords. */ - function requestRandomWords(VRFV2PlusClient.RandomWordsRequest calldata req) external nonReentrant returns (uint256) { + function requestRandomWords( + VRFV2PlusClient.RandomWordsRequest calldata req + ) external override nonReentrant returns (uint256) { // Input validation using the subscription storage. if (s_subscriptionConfigs[req.subId].owner == address(0)) { revert InvalidSubscription(); @@ -427,11 +431,11 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { nativePayment ); if (nativePayment) { - if (s_subscriptions[rc.subId].ethBalance < payment) { + if (s_subscriptions[rc.subId].nativeBalance < payment) { revert InsufficientBalance(); } - s_subscriptions[rc.subId].ethBalance -= payment; - s_withdrawableEth[s_provingKeys[output.keyHash]] += payment; + s_subscriptions[rc.subId].nativeBalance -= payment; + s_withdrawableNative[s_provingKeys[output.keyHash]] += payment; } else { if (s_subscriptions[rc.subId].balance < payment) { revert InsufficientBalance(); @@ -456,10 +460,10 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { ) internal view returns (uint96) { if (nativePayment) { return - calculatePaymentAmountEth( + calculatePaymentAmountNative( startGas, gasAfterPaymentCalculation, - s_feeConfig.fulfillmentFlatFeeEthPPM, + s_feeConfig.fulfillmentFlatFeeNativePPM, weiPerUnitGas ); } @@ -472,7 +476,7 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { ); } - function calculatePaymentAmountEth( + function calculatePaymentAmountNative( uint256 startGas, uint256 gasAfterPaymentCalculation, uint32 fulfillmentFlatFeePPM, @@ -517,7 +521,7 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { bool staleFallback = stalenessSeconds > 0; uint256 timestamp; int256 weiPerUnitLink; - (, weiPerUnitLink, , timestamp, ) = LINK_ETH_FEED.latestRoundData(); + (, weiPerUnitLink, , timestamp, ) = LINK_NATIVE_FEED.latestRoundData(); // solhint-disable-next-line not-rely-on-time if (staleFallback && stalenessSeconds < block.timestamp - timestamp) { weiPerUnitLink = s_fallbackWeiPerUnitLink; @@ -525,16 +529,10 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { return weiPerUnitLink; } - /* - * @notice Check to see if there exists a request commitment consumers - * for all consumers and keyhashes for a given sub. - * @param subId - ID of the subscription - * @return true if there exists at least one unfulfilled request for the subscription, false - * otherwise. - * @dev Looping is bounded to MAX_CONSUMERS*(number of keyhashes). - * @dev Used to disable subscription canceling while outstanding request are present. + /** + * @inheritdoc IVRFSubscriptionV2Plus */ - function pendingRequestExists(uint256 subId) public view returns (bool) { + function pendingRequestExists(uint256 subId) public view override returns (bool) { SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId]; for (uint256 i = 0; i < subConfig.consumers.length; i++) { for (uint256 j = 0; j < s_provingKeyHashes.length; j++) { @@ -619,7 +617,7 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { address subOwner; address[] consumers; uint96 linkBalance; - uint96 ethBalance; + uint96 nativeBalance; } function isTargetRegistered(address target) internal view returns (bool) { @@ -657,7 +655,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 nativeBalance, , address owner, address[] memory consumers) = getSubscription(subId); require(owner == msg.sender, "Not subscription owner"); require(!pendingRequestExists(subId), "Pending request exists"); @@ -667,11 +665,11 @@ contract VRFCoordinatorV2Plus is VRF, SubscriptionAPI { subOwner: owner, consumers: consumers, linkBalance: balance, - ethBalance: ethBalance + nativeBalance: nativeBalance }); bytes memory encodedData = abi.encode(migrationData); deleteSubscription(subId); - IVRFCoordinatorV2PlusMigration(newCoordinator).onMigration{value: ethBalance}(encodedData); + IVRFCoordinatorV2PlusMigration(newCoordinator).onMigration{value: nativeBalance}(encodedData); // Only transfer LINK if the token is active and there is a balance. if (address(LINK) != address(0) && balance != 0) { diff --git a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol index ed4679b7d6..cd453c2639 100644 --- a/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol +++ b/contracts/src/v0.8/dev/vrf/VRFV2PlusWrapper.sol @@ -21,40 +21,35 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume error LinkAlreadySet(); error FailedToTransferLink(); - LinkTokenInterface public s_link; - AggregatorV3Interface public s_linkEthFeed; - ExtendedVRFCoordinatorV2PlusInterface public immutable COORDINATOR; + /* Storage Slot 1: BEGIN */ + // s_keyHash is the key hash to use when requesting randomness. Fees are paid based on current gas + // fees, so this should be set to the highest gas lane on the network. + bytes32 s_keyHash; + /* Storage Slot 1: END */ + + /* Storage Slot 2: BEGIN */ uint256 public immutable SUBSCRIPTION_ID; - /// @dev this is the size of a VRF v2 fulfillment's calldata abi-encoded in bytes. - /// @dev proofSize = 13 words = 13 * 256 = 3328 bits - /// @dev commitmentSize = 5 words = 5 * 256 = 1280 bits - /// @dev dataSize = proofSize + commitmentSize = 4608 bits - /// @dev selector = 32 bits - /// @dev total data size = 4608 bits + 32 bits = 4640 bits = 580 bytes - uint32 public s_fulfillmentTxSizeBytes = 580; + /* Storage Slot 2: END */ + /* Storage Slot 3: BEGIN */ // 5k is plenty for an EXTCODESIZE call (2600) + warm CALL (100) // and some arithmetic operations. uint256 private constant GAS_FOR_CALL_EXACT_CHECK = 5_000; + /* Storage Slot 3: END */ + /* Storage Slot 4: BEGIN */ // lastRequestId is the request ID of the most recent VRF V2 request made by this wrapper. This // should only be relied on within the same transaction the request was made. uint256 public override lastRequestId; + /* Storage Slot 4: END */ - // Configuration fetched from VRFCoordinatorV2 - - // s_configured tracks whether this contract has been configured. If not configured, randomness - // requests cannot be made. - bool public s_configured; - - // s_disabled disables the contract when true. When disabled, new VRF requests cannot be made - // but existing ones can still be fulfilled. - bool public s_disabled; - + /* Storage Slot 5: BEGIN */ // s_fallbackWeiPerUnitLink is the backup LINK exchange rate used when the LINK/NATIVE feed is // stale. int256 private s_fallbackWeiPerUnitLink; + /* Storage Slot 5: END */ + /* Storage Slot 6: BEGIN */ // s_stalenessSeconds is the number of seconds before we consider the feed price to be stale and // fallback to fallbackWeiPerUnitLink. uint32 private s_stalenessSeconds; @@ -65,51 +60,78 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume // s_fulfillmentFlatFeeLinkPPM is the flat fee in millionths of LINK that VRFCoordinatorV2 // charges. - uint32 private s_fulfillmentFlatFeeEthPPM; + uint32 private s_fulfillmentFlatFeeNativePPM; - // Other configuration + LinkTokenInterface public s_link; + /* Storage Slot 6: END */ + /* Storage Slot 7: BEGIN */ // s_wrapperGasOverhead reflects the gas overhead of the wrapper's fulfillRandomWords // function. The cost for this gas is passed to the user. uint32 private s_wrapperGasOverhead; + // Configuration fetched from VRFCoordinatorV2 + + /// @dev this is the size of a VRF v2 fulfillment's calldata abi-encoded in bytes. + /// @dev proofSize = 13 words = 13 * 256 = 3328 bits + /// @dev commitmentSize = 5 words = 5 * 256 = 1280 bits + /// @dev dataSize = proofSize + commitmentSize = 4608 bits + /// @dev selector = 32 bits + /// @dev total data size = 4608 bits + 32 bits = 4640 bits = 580 bytes + uint32 public s_fulfillmentTxSizeBytes = 580; + // s_coordinatorGasOverhead reflects the gas overhead of the coordinator's fulfillRandomWords // function. The cost for this gas is billed to the subscription, and must therefor be included // in the pricing for wrapped requests. This includes the gas costs of proof verification and // payment calculation in the coordinator. uint32 private s_coordinatorGasOverhead; + AggregatorV3Interface public s_linkNativeFeed; + /* Storage Slot 7: END */ + + /* Storage Slot 8: BEGIN */ + // s_configured tracks whether this contract has been configured. If not configured, randomness + // requests cannot be made. + bool public s_configured; + + // s_disabled disables the contract when true. When disabled, new VRF requests cannot be made + // but existing ones can still be fulfilled. + bool public s_disabled; + // s_wrapperPremiumPercentage is the premium ratio in percentage. For example, a value of 0 // indicates no premium. A value of 15 indicates a 15 percent premium. uint8 private s_wrapperPremiumPercentage; - // s_keyHash is the key hash to use when requesting randomness. Fees are paid based on current gas - // fees, so this should be set to the highest gas lane on the network. - bytes32 s_keyHash; - // s_maxNumWords is the max number of words that can be requested in a single wrapped VRF request. uint8 s_maxNumWords; + /* Storage Slot 8: END */ struct Callback { address callbackAddress; uint32 callbackGasLimit; - uint256 requestGasPrice; + // Reducing requestGasPrice from uint256 to uint64 slots Callback struct + // into a single word, thus saving an entire SSTORE and leading to 21K + // gas cost saving. 18 ETH would be the max gas price we can process. + // GasPrice is unlikely to be more than 14 ETH on most chains + uint64 requestGasPrice; } + /* Storage Slot 9: BEGIN */ mapping(uint256 => Callback) /* requestID */ /* callback */ public s_callbacks; - constructor(address _link, address _linkEthFeed, address _coordinator) VRFConsumerBaseV2Plus(_coordinator) { + /* Storage Slot 9: END */ + + constructor(address _link, address _linkNativeFeed, address _coordinator) VRFConsumerBaseV2Plus(_coordinator) { if (_link != address(0)) { s_link = LinkTokenInterface(_link); } - if (_linkEthFeed != address(0)) { - s_linkEthFeed = AggregatorV3Interface(_linkEthFeed); + if (_linkNativeFeed != address(0)) { + s_linkNativeFeed = AggregatorV3Interface(_linkNativeFeed); } - COORDINATOR = ExtendedVRFCoordinatorV2PlusInterface(_coordinator); // Create this wrapper's subscription and add itself as a consumer. - uint256 subId = ExtendedVRFCoordinatorV2PlusInterface(_coordinator).createSubscription(); + uint256 subId = s_vrfCoordinator.createSubscription(); SUBSCRIPTION_ID = subId; - ExtendedVRFCoordinatorV2PlusInterface(_coordinator).addConsumer(subId, address(this)); + s_vrfCoordinator.addConsumer(subId, address(this)); } /** @@ -125,11 +147,11 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume } /** - * @notice set the link eth feed to be used by this wrapper - * @param linkEthFeed address of the link eth feed + * @notice set the link native feed to be used by this wrapper + * @param linkNativeFeed address of the link native feed */ - function setLinkEthFeed(address linkEthFeed) external onlyOwner { - s_linkEthFeed = AggregatorV3Interface(linkEthFeed); + function setLinkNativeFeed(address linkNativeFeed) external onlyOwner { + s_linkNativeFeed = AggregatorV3Interface(linkNativeFeed); } /** @@ -161,7 +183,11 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume uint32 _coordinatorGasOverhead, uint8 _wrapperPremiumPercentage, bytes32 _keyHash, - uint8 _maxNumWords + uint8 _maxNumWords, + uint32 stalenessSeconds, + int256 fallbackWeiPerUnitLink, + uint32 fulfillmentFlatFeeLinkPPM, + uint32 fulfillmentFlatFeeNativePPM ) external onlyOwner { s_wrapperGasOverhead = _wrapperGasOverhead; s_coordinatorGasOverhead = _coordinatorGasOverhead; @@ -171,9 +197,10 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume s_configured = true; // Get other configuration from coordinator - (, , s_stalenessSeconds, ) = COORDINATOR.s_config(); - s_fallbackWeiPerUnitLink = COORDINATOR.s_fallbackWeiPerUnitLink(); - (s_fulfillmentFlatFeeLinkPPM, s_fulfillmentFlatFeeEthPPM) = COORDINATOR.s_feeConfig(); + s_stalenessSeconds = stalenessSeconds; + s_fallbackWeiPerUnitLink = fallbackWeiPerUnitLink; + s_fulfillmentFlatFeeLinkPPM = fulfillmentFlatFeeLinkPPM; + s_fulfillmentFlatFeeNativePPM = fulfillmentFlatFeeNativePPM; } /** @@ -288,7 +315,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume // feeWithPremium is the fee after the percentage premium is applied uint256 feeWithPremium = (baseFee * (s_wrapperPremiumPercentage + 100)) / 100; // feeWithFlatFee is the fee after the flat fee is applied on top of the premium - uint256 feeWithFlatFee = feeWithPremium + (1e12 * uint256(s_fulfillmentFlatFeeEthPPM)); + uint256 feeWithFlatFee = feeWithPremium + (1e12 * uint256(s_fulfillmentFlatFeeNativePPM)); return feeWithFlatFee; } @@ -348,11 +375,11 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume numWords: numWords, extraArgs: "" // empty extraArgs defaults to link payment }); - uint256 requestId = COORDINATOR.requestRandomWords(req); + uint256 requestId = s_vrfCoordinator.requestRandomWords(req); s_callbacks[requestId] = Callback({ callbackAddress: _sender, callbackGasLimit: callbackGasLimit, - requestGasPrice: tx.gasprice + requestGasPrice: uint64(tx.gasprice) }); lastRequestId = requestId; } @@ -374,11 +401,11 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume numWords: _numWords, extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true})) }); - requestId = COORDINATOR.requestRandomWords(req); + requestId = s_vrfCoordinator.requestRandomWords(req); s_callbacks[requestId] = Callback({ callbackAddress: msg.sender, callbackGasLimit: _callbackGasLimit, - requestGasPrice: tx.gasprice + requestGasPrice: uint64(tx.gasprice) }); return requestId; @@ -442,7 +469,7 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume bool staleFallback = s_stalenessSeconds > 0; uint256 timestamp; int256 weiPerUnitLink; - (, weiPerUnitLink, , timestamp, ) = s_linkEthFeed.latestRoundData(); + (, weiPerUnitLink, , timestamp, ) = s_linkNativeFeed.latestRoundData(); // solhint-disable-next-line not-rely-on-time if (staleFallback && s_stalenessSeconds < block.timestamp - timestamp) { weiPerUnitLink = s_fallbackWeiPerUnitLink; @@ -502,19 +529,3 @@ contract VRFV2PlusWrapper is ConfirmedOwner, TypeAndVersionInterface, VRFConsume _; } } - -interface ExtendedVRFCoordinatorV2PlusInterface is IVRFCoordinatorV2Plus { - function s_config() - external - view - returns ( - uint16 minimumRequestConfirmations, - uint32 maxGasLimit, - uint32 stalenessSeconds, - uint32 gasAfterPaymentCalculation - ); - - function s_fallbackWeiPerUnitLink() external view returns (int256); - - function s_feeConfig() external view returns (uint32 fulfillmentFlatFeeLinkPPM, uint32 fulfillmentFlatFeeEthPPM); -} diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol similarity index 72% rename from contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol rename to contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol index 0d49386737..5e54636bb1 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol @@ -2,13 +2,13 @@ pragma solidity ^0.8.4; import "../../../vrf/VRF.sol"; -import {VRFCoordinatorV2Plus} from "../VRFCoordinatorV2Plus.sol"; +import {VRFCoordinatorV2_5} from "../VRFCoordinatorV2_5.sol"; import "../../../vendor/openzeppelin-solidity/v4.7.3/contracts/utils/structs/EnumerableSet.sol"; -contract ExposedVRFCoordinatorV2Plus is VRFCoordinatorV2Plus { +contract ExposedVRFCoordinatorV2_5 is VRFCoordinatorV2_5 { using EnumerableSet for EnumerableSet.UintSet; - constructor(address blockhashStore) VRFCoordinatorV2Plus(blockhashStore) {} + constructor(address blockhashStore) VRFCoordinatorV2_5(blockhashStore) {} function computeRequestIdExternal( bytes32 keyHash, @@ -46,8 +46,8 @@ contract ExposedVRFCoordinatorV2Plus is VRFCoordinatorV2Plus { s_totalBalance = newBalance; } - function setTotalEthBalanceTestingOnlyXXX(uint96 newBalance) external { - s_totalEthBalance = newBalance; + function setTotalNativeBalanceTestingOnlyXXX(uint96 newBalance) external { + s_totalNativeBalance = newBalance; } function setWithdrawableTokensTestingOnlyXXX(address oracle, uint96 newBalance) external { @@ -58,11 +58,11 @@ contract ExposedVRFCoordinatorV2Plus is VRFCoordinatorV2Plus { return s_withdrawableTokens[oracle]; } - function setWithdrawableEthTestingOnlyXXX(address oracle, uint96 newBalance) external { - s_withdrawableEth[oracle] = newBalance; + function setWithdrawableNativeTestingOnlyXXX(address oracle, uint96 newBalance) external { + s_withdrawableNative[oracle] = newBalance; } - function getWithdrawableEthTestingOnlyXXX(address oracle) external view returns (uint96) { - return s_withdrawableEth[oracle]; + function getWithdrawableNativeTestingOnlyXXX(address oracle) external view returns (uint96) { + return s_withdrawableNative[oracle]; } } diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol index 5e059a067a..a8d2abfc4b 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol @@ -17,7 +17,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is VRF, SubscriptionAPI, IVRFCoordinatorV2PlusMigration, - IVRFMigratableCoordinatorV2Plus + IVRFCoordinatorV2Plus { using EnumerableSet for EnumerableSet.UintSet; /// @dev should always be available @@ -89,9 +89,9 @@ contract VRFCoordinatorV2PlusUpgradedVersion is // Flat fee charged per fulfillment in millionths of link // So fee range is [0, 2^32/10^6]. uint32 fulfillmentFlatFeeLinkPPM; - // Flat fee charged per fulfillment in millionths of eth. + // Flat fee charged per fulfillment in millionths of native. // So fee range is [0, 2^32/10^6]. - uint32 fulfillmentFlatFeeEthPPM; + uint32 fulfillmentFlatFeeNativePPM; } event ConfigSet( @@ -134,9 +134,9 @@ contract VRFCoordinatorV2PlusUpgradedVersion is * @notice Sets the configuration of the vrfv2 coordinator * @param minimumRequestConfirmations global min for request confirmations * @param maxGasLimit global max for request gas limit - * @param stalenessSeconds if the eth/link feed is more stale then this, use the fallback price + * @param stalenessSeconds if the native/link feed is more stale then this, use the fallback price * @param gasAfterPaymentCalculation gas used in doing accounting after completing the gas measurement - * @param fallbackWeiPerUnitLink fallback eth/link price in the case of a stale feed + * @param fallbackWeiPerUnitLink fallback native/link price in the case of a stale feed * @param feeConfig fee configuration */ function setConfig( @@ -219,7 +219,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is * 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. * extraArgs - Encoded extra arguments that has a boolean flag for whether payment - * should be made in ETH or LINK. Payment in LINK is only available if the LINK token is available to this contract. + * should be made in native or LINK. Payment in LINK is only available if the LINK token is available to this contract. * @return requestId - A unique identifier of the request. Can be used to match * a request to a response in fulfillRandomWords. */ @@ -424,11 +424,11 @@ contract VRFCoordinatorV2PlusUpgradedVersion is nativePayment ); if (nativePayment) { - if (s_subscriptions[rc.subId].ethBalance < payment) { + if (s_subscriptions[rc.subId].nativeBalance < payment) { revert InsufficientBalance(); } - s_subscriptions[rc.subId].ethBalance -= payment; - s_withdrawableEth[s_provingKeys[output.keyHash]] += payment; + s_subscriptions[rc.subId].nativeBalance -= payment; + s_withdrawableNative[s_provingKeys[output.keyHash]] += payment; } else { if (s_subscriptions[rc.subId].balance < payment) { revert InsufficientBalance(); @@ -453,10 +453,10 @@ contract VRFCoordinatorV2PlusUpgradedVersion is ) internal view returns (uint96) { if (nativePayment) { return - calculatePaymentAmountEth( + calculatePaymentAmountNative( startGas, gasAfterPaymentCalculation, - s_feeConfig.fulfillmentFlatFeeEthPPM, + s_feeConfig.fulfillmentFlatFeeNativePPM, weiPerUnitGas ); } @@ -469,7 +469,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is ); } - function calculatePaymentAmountEth( + function calculatePaymentAmountNative( uint256 startGas, uint256 gasAfterPaymentCalculation, uint32 fulfillmentFlatFeePPM, @@ -514,7 +514,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is bool staleFallback = stalenessSeconds > 0; uint256 timestamp; int256 weiPerUnitLink; - (, weiPerUnitLink, , timestamp, ) = LINK_ETH_FEED.latestRoundData(); + (, weiPerUnitLink, , timestamp, ) = LINK_NATIVE_FEED.latestRoundData(); // solhint-disable-next-line not-rely-on-time if (staleFallback && stalenessSeconds < block.timestamp - timestamp) { weiPerUnitLink = s_fallbackWeiPerUnitLink; @@ -531,7 +531,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is * @dev Looping is bounded to MAX_CONSUMERS*(number of keyhashes). * @dev Used to disable subscription canceling while outstanding request are present. */ - function pendingRequestExists(uint256 subId) public view returns (bool) { + function pendingRequestExists(uint256 subId) public view override returns (bool) { SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId]; for (uint256 i = 0; i < subConfig.consumers.length; i++) { for (uint256 j = 0; j < s_provingKeyHashes.length; j++) { @@ -613,7 +613,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is address subOwner; address[] consumers; uint96 linkBalance; - uint96 ethBalance; + uint96 nativeBalance; } function isTargetRegistered(address target) internal view returns (bool) { @@ -637,7 +637,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is if (!isTargetRegistered(newCoordinator)) { revert CoordinatorNotRegistered(newCoordinator); } - (uint96 balance, uint96 ethBalance, , address owner, address[] memory consumers) = getSubscription(subId); + (uint96 balance, uint96 nativeBalance, , address owner, address[] memory consumers) = getSubscription(subId); require(owner == msg.sender, "Not subscription owner"); require(!pendingRequestExists(subId), "Pending request exists"); @@ -647,11 +647,11 @@ contract VRFCoordinatorV2PlusUpgradedVersion is subOwner: owner, consumers: consumers, linkBalance: balance, - ethBalance: ethBalance + nativeBalance: nativeBalance }); bytes memory encodedData = abi.encode(migrationData); deleteSubscription(subId); - IVRFCoordinatorV2PlusMigration(newCoordinator).onMigration{value: ethBalance}(encodedData); + IVRFCoordinatorV2PlusMigration(newCoordinator).onMigration{value: nativeBalance}(encodedData); // Only transfer LINK if the token is active and there is a balance. if (address(LINK) != address(0) && balance != 0) { @@ -683,8 +683,8 @@ contract VRFCoordinatorV2PlusUpgradedVersion is revert InvalidVersion(migrationData.fromVersion, 1); } - if (msg.value != uint256(migrationData.ethBalance)) { - revert InvalidNativeBalance(msg.value, migrationData.ethBalance); + if (msg.value != uint256(migrationData.nativeBalance)) { + revert InvalidNativeBalance(msg.value, migrationData.nativeBalance); } // it should be impossible to have a subscription id collision, for two reasons: @@ -704,7 +704,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is } s_subscriptions[migrationData.subId] = Subscription({ - ethBalance: migrationData.ethBalance, + nativeBalance: migrationData.nativeBalance, balance: migrationData.linkBalance, reqCount: 0 }); @@ -715,7 +715,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is }); s_totalBalance += uint96(migrationData.linkBalance); - s_totalEthBalance += uint96(migrationData.ethBalance); + s_totalNativeBalance += uint96(migrationData.nativeBalance); s_subIds.add(migrationData.subId); } 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 fd6d5b2f09..52a5b864c6 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol @@ -3,19 +3,20 @@ pragma solidity ^0.8.4; import "../../../shared/interfaces/LinkTokenInterface.sol"; import "../../interfaces/IVRFCoordinatorV2PlusMigration.sol"; -import "../../interfaces/IVRFMigratableCoordinatorV2Plus.sol"; +import "../../interfaces/IVRFCoordinatorV2Plus.sol"; import "../VRFConsumerBaseV2Plus.sol"; /// @dev this contract is only meant for testing migration /// @dev it is a simplified example of future version (V2) of VRFCoordinatorV2Plus -contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration, IVRFMigratableCoordinatorV2Plus { +contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration { error SubscriptionIDCollisionFound(); struct Subscription { - address owner; - address[] consumers; uint96 linkBalance; uint96 nativeBalance; + uint64 reqCount; + address owner; + address[] consumers; } mapping(uint256 => Subscription) public s_subscriptions; /* subId */ /* subscription */ @@ -44,15 +45,20 @@ contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration, IVRFM function getSubscription( uint256 subId - ) public view returns (address owner, address[] memory consumers, uint96 linkBalance, uint96 nativeBalance) { + ) + public + view + returns (uint96 linkBalance, uint96 nativeBalance, uint64 reqCount, address owner, address[] memory consumers) + { if (s_subscriptions[subId].owner == address(0)) { revert InvalidSubscription(); } return ( - s_subscriptions[subId].owner, - s_subscriptions[subId].consumers, s_subscriptions[subId].linkBalance, - s_subscriptions[subId].nativeBalance + s_subscriptions[subId].nativeBalance, + s_subscriptions[subId].reqCount, + s_subscriptions[subId].owner, + s_subscriptions[subId].consumers ); } @@ -78,7 +84,7 @@ contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration, IVRFM address subOwner; address[] consumers; uint96 linkBalance; - uint96 ethBalance; + uint96 nativeBalance; } /** @@ -95,8 +101,8 @@ contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration, IVRFM revert InvalidVersion(migrationData.fromVersion, 1); } - if (msg.value != uint256(migrationData.ethBalance)) { - revert InvalidNativeBalance(msg.value, migrationData.ethBalance); + if (msg.value != uint256(migrationData.nativeBalance)) { + revert InvalidNativeBalance(msg.value, migrationData.nativeBalance); } // it should be impossible to have a subscription id collision, for two reasons: @@ -112,12 +118,13 @@ contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration, IVRFM } s_subscriptions[migrationData.subId] = Subscription({ + nativeBalance: migrationData.nativeBalance, + linkBalance: migrationData.linkBalance, + reqCount: 0, owner: migrationData.subOwner, - consumers: migrationData.consumers, - nativeBalance: migrationData.ethBalance, - linkBalance: migrationData.linkBalance + consumers: migrationData.consumers }); - s_totalNativeBalance += migrationData.ethBalance; + s_totalNativeBalance += migrationData.nativeBalance; s_totalLinkBalance += migrationData.linkBalance; } @@ -125,12 +132,9 @@ contract VRFCoordinatorV2Plus_V2Example is IVRFCoordinatorV2PlusMigration, IVRFM * Section: Request/Response **************************************************************************/ - /** - * @inheritdoc IVRFMigratableCoordinatorV2Plus - */ - function requestRandomWords( - VRFV2PlusClient.RandomWordsRequest calldata /* req */ - ) external override returns (uint256 requestId) { + function requestRandomWords(VRFV2PlusClient.RandomWordsRequest calldata req) external returns (uint256 requestId) { + Subscription memory sub = s_subscriptions[req.subId]; + sub.reqCount = sub.reqCount + 1; return handleRequest(msg.sender); } diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol index ff9245b688..948cc17b3f 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol @@ -42,7 +42,7 @@ contract VRFV2PlusConsumerExample is ConfirmedOwner, VRFConsumerBaseV2Plus { function createSubscriptionAndFundNative() external payable { subscribe(); - s_vrfCoordinatorApiV1.fundSubscriptionWithEth{value: msg.value}(s_subId); + s_vrfCoordinatorApiV1.fundSubscriptionWithNative{value: msg.value}(s_subId); } function createSubscriptionAndFund(uint96 amount) external { @@ -58,7 +58,7 @@ contract VRFV2PlusConsumerExample is ConfirmedOwner, VRFConsumerBaseV2Plus { function topUpSubscriptionNative() external payable { require(s_subId != 0, "sub not set"); - s_vrfCoordinatorApiV1.fundSubscriptionWithEth{value: msg.value}(s_subId); + s_vrfCoordinatorApiV1.fundSubscriptionWithNative{value: msg.value}(s_subId); } function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override { diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol index f7b2233246..b1dca81ebd 100644 --- a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusMaliciousMigrator.sol @@ -2,14 +2,14 @@ pragma solidity ^0.8.0; import "../../interfaces/IVRFMigratableConsumerV2Plus.sol"; -import "../../interfaces/IVRFMigratableCoordinatorV2Plus.sol"; +import "../../interfaces/IVRFCoordinatorV2Plus.sol"; import "../libraries/VRFV2PlusClient.sol"; contract VRFV2PlusMaliciousMigrator is IVRFMigratableConsumerV2Plus { - IVRFMigratableCoordinatorV2Plus s_vrfCoordinator; + IVRFCoordinatorV2Plus s_vrfCoordinator; constructor(address _vrfCoordinator) { - s_vrfCoordinator = IVRFMigratableCoordinatorV2Plus(_vrfCoordinator); + s_vrfCoordinator = IVRFCoordinatorV2Plus(_vrfCoordinator); } /** diff --git a/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol new file mode 100644 index 0000000000..4f63bc0e32 --- /dev/null +++ b/contracts/src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperLoadTestConsumer.sol @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.6; + +import "../VRFV2PlusWrapperConsumerBase.sol"; +import "../../../shared/access/ConfirmedOwner.sol"; +import "../../../ChainSpecificUtil.sol"; + +contract VRFV2PlusWrapperLoadTestConsumer is VRFV2PlusWrapperConsumerBase, ConfirmedOwner { + 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 + + event WrappedRequestFulfilled(uint256 requestId, uint256[] randomWords, uint256 payment); + event WrapperRequestMade(uint256 indexed requestId, uint256 paid); + + struct RequestStatus { + uint256 paid; + bool fulfilled; + uint256[] randomWords; + uint requestTimestamp; + uint fulfilmentTimestamp; + uint256 requestBlockNumber; + uint256 fulfilmentBlockNumber; + bool native; + } + + mapping(uint256 => RequestStatus) /* requestId */ /* requestStatus */ public s_requests; + + constructor( + address _link, + address _vrfV2PlusWrapper + ) ConfirmedOwner(msg.sender) VRFV2PlusWrapperConsumerBase(_link, _vrfV2PlusWrapper) {} + + function makeRequests( + uint32 _callbackGasLimit, + uint16 _requestConfirmations, + uint32 _numWords, + uint16 _requestCount + ) external onlyOwner { + for (uint16 i = 0; i < _requestCount; i++) { + uint256 requestId = requestRandomness(_callbackGasLimit, _requestConfirmations, _numWords); + s_lastRequestId = requestId; + + uint256 requestBlockNumber = ChainSpecificUtil.getBlockNumber(); + uint256 paid = VRF_V2_PLUS_WRAPPER.calculateRequestPrice(_callbackGasLimit); + s_requests[requestId] = RequestStatus({ + paid: paid, + fulfilled: false, + randomWords: new uint256[](0), + requestTimestamp: block.timestamp, + requestBlockNumber: requestBlockNumber, + fulfilmentTimestamp: 0, + fulfilmentBlockNumber: 0, + native: false + }); + s_requestCount++; + requestHeights[requestId] = requestBlockNumber; + emit WrapperRequestMade(requestId, paid); + } + } + + function makeRequestsNative( + uint32 _callbackGasLimit, + uint16 _requestConfirmations, + uint32 _numWords, + uint16 _requestCount + ) external onlyOwner { + for (uint16 i = 0; i < _requestCount; i++) { + uint256 requestId = requestRandomnessPayInNative(_callbackGasLimit, _requestConfirmations, _numWords); + s_lastRequestId = requestId; + + uint256 requestBlockNumber = ChainSpecificUtil.getBlockNumber(); + uint256 paid = VRF_V2_PLUS_WRAPPER.calculateRequestPriceNative(_callbackGasLimit); + s_requests[requestId] = RequestStatus({ + paid: paid, + fulfilled: false, + randomWords: new uint256[](0), + requestTimestamp: block.timestamp, + requestBlockNumber: requestBlockNumber, + fulfilmentTimestamp: 0, + fulfilmentBlockNumber: 0, + native: true + }); + s_requestCount++; + requestHeights[requestId] = requestBlockNumber; + emit WrapperRequestMade(requestId, paid); + } + } + + function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { + require(s_requests[_requestId].paid > 0, "request not found"); + 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_responseCount++; + s_requests[_requestId].fulfilled = true; + s_requests[_requestId].randomWords = _randomWords; + s_requests[_requestId].fulfilmentTimestamp = block.timestamp; + s_requests[_requestId].fulfilmentBlockNumber = fulfilmentBlockNumber; + + emit WrappedRequestFulfilled(_requestId, _randomWords, s_requests[_requestId].paid); + } + + function getRequestStatus( + uint256 _requestId + ) + external + view + returns ( + uint256 paid, + bool fulfilled, + uint256[] memory randomWords, + uint requestTimestamp, + uint fulfilmentTimestamp, + uint256 requestBlockNumber, + uint256 fulfilmentBlockNumber + ) + { + require(s_requests[_requestId].paid > 0, "request not found"); + RequestStatus memory request = s_requests[_requestId]; + return ( + request.paid, + request.fulfilled, + request.randomWords, + request.requestTimestamp, + request.fulfilmentTimestamp, + request.requestBlockNumber, + request.fulfilmentBlockNumber + ); + } + + function reset() external { + s_averageFulfillmentInMillions = 0; // in millions for better precision + s_slowestFulfillment = 0; + s_fastestFulfillment = 999; + s_requestCount = 0; + s_responseCount = 0; + } + + /// @notice withdrawLink withdraws the amount specified in amount to the owner + /// @param amount the amount to withdraw, in juels + function withdrawLink(uint256 amount) external onlyOwner { + LINK.transfer(owner(), amount); + } + + /// @notice withdrawNative withdraws the amount specified in amount to the owner + /// @param amount the amount to withdraw, in wei + function withdrawNative(uint256 amount) external onlyOwner { + (bool success, ) = payable(owner()).call{value: amount}(""); + require(success, "withdrawNative failed"); + } + + function getWrapper() external view returns (VRFV2PlusWrapperInterface) { + return VRF_V2_PLUS_WRAPPER; + } + + receive() external payable {} + + function getBalance() public view returns (uint) { + return address(this).balance; + } +} diff --git a/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Mock.t.sol b/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Mock.t.sol index ee184bd145..dd607f2ce7 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Mock.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Mock.t.sol @@ -6,7 +6,6 @@ import {MockLinkToken} from "../../../../src/v0.8/mocks/MockLinkToken.sol"; import {MockV3Aggregator} from "../../../../src/v0.8/tests/MockV3Aggregator.sol"; import {VRFCoordinatorV2Mock} from "../../../../src/v0.8/mocks/VRFCoordinatorV2Mock.sol"; import {VRFConsumerV2} from "../../../../src/v0.8/vrf/testhelpers/VRFConsumerV2.sol"; -import {VRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol"; contract VRFCoordinatorV2MockTest is BaseTest { MockLinkToken internal s_linkToken; 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 41cb24492c..a847bd5bee 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Plus_Migration.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFCoordinatorV2Plus_Migration.t.sol @@ -2,8 +2,8 @@ pragma solidity 0.8.6; import "../BaseTest.t.sol"; import {VRFCoordinatorV2Plus_V2Example} from "../../../../src/v0.8/dev/vrf/testhelpers/VRFCoordinatorV2Plus_V2Example.sol"; -import {ExposedVRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol"; -import {VRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol"; +import {ExposedVRFCoordinatorV2_5} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol"; +import {VRFCoordinatorV2_5} from "../../../../src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol"; import {SubscriptionAPI} from "../../../../src/v0.8/dev/vrf/SubscriptionAPI.sol"; import {VRFV2PlusConsumerExample} from "../../../../src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol"; import {MockLinkToken} from "../../../../src/v0.8/mocks/MockLinkToken.sol"; @@ -24,9 +24,9 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { hex"a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c701"; bytes32 internal constant KEY_HASH = hex"9f2353bde94264dbc3d554a94cceba2d7d2b4fdce4304d3e09a1fea9fbeb1528"; - ExposedVRFCoordinatorV2Plus v1Coordinator; + ExposedVRFCoordinatorV2_5 v1Coordinator; VRFCoordinatorV2Plus_V2Example v2Coordinator; - ExposedVRFCoordinatorV2Plus v1Coordinator_noLink; + ExposedVRFCoordinatorV2_5 v1Coordinator_noLink; VRFCoordinatorV2Plus_V2Example v2Coordinator_noLink; uint256 subId; uint256 subId_noLink; @@ -34,7 +34,7 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { VRFV2PlusConsumerExample testConsumer_noLink; MockLinkToken linkToken; address linkTokenAddr; - MockV3Aggregator linkEthFeed; + MockV3Aggregator linkNativeFeed; address v1CoordinatorAddr; address v2CoordinatorAddr; address v1CoordinatorAddr_noLink; @@ -48,13 +48,13 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { BaseTest.setUp(); vm.deal(OWNER, 100 ether); address bhs = makeAddr("bhs"); - v1Coordinator = new ExposedVRFCoordinatorV2Plus(bhs); - v1Coordinator_noLink = new ExposedVRFCoordinatorV2Plus(bhs); + v1Coordinator = new ExposedVRFCoordinatorV2_5(bhs); + v1Coordinator_noLink = new ExposedVRFCoordinatorV2_5(bhs); subId = v1Coordinator.createSubscription(); subId_noLink = v1Coordinator_noLink.createSubscription(); linkToken = new MockLinkToken(); - linkEthFeed = new MockV3Aggregator(18, 500000000000000000); // .5 ETH (good for testing) - v1Coordinator.setLINKAndLINKETHFeed(address(linkToken), address(linkEthFeed)); + linkNativeFeed = new MockV3Aggregator(18, 500000000000000000); // .5 ETH (good for testing) + v1Coordinator.setLINKAndLINKNativeFeed(address(linkToken), address(linkNativeFeed)); linkTokenAddr = address(linkToken); v2Coordinator = new VRFCoordinatorV2Plus_V2Example(address(linkToken), address(v1Coordinator)); v2Coordinator_noLink = new VRFCoordinatorV2Plus_V2Example(address(0), address(v1Coordinator_noLink)); @@ -91,7 +91,7 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { 600, 10_000, 20_000, - VRFCoordinatorV2Plus.FeeConfig({fulfillmentFlatFeeLinkPPM: 200, fulfillmentFlatFeeEthPPM: 100}) + VRFCoordinatorV2_5.FeeConfig({fulfillmentFlatFeeLinkPPM: 200, fulfillmentFlatFeeNativePPM: 100}) ); v1Coordinator_noLink.setConfig( DEFAULT_REQUEST_CONFIRMATIONS, @@ -99,7 +99,7 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { 600, 10_000, 20_000, - VRFCoordinatorV2Plus.FeeConfig({fulfillmentFlatFeeLinkPPM: 200, fulfillmentFlatFeeEthPPM: 100}) + VRFCoordinatorV2_5.FeeConfig({fulfillmentFlatFeeLinkPPM: 200, fulfillmentFlatFeeNativePPM: 100}) ); registerProvingKey(); testConsumer.setCoordinator(v1CoordinatorAddr); @@ -117,7 +117,7 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { v1Coordinator.deregisterMigratableCoordinator(v2CoordinatorAddr); assertFalse(v1Coordinator.isTargetRegisteredExternal(v2CoordinatorAddr)); - vm.expectRevert(abi.encodeWithSelector(VRFCoordinatorV2Plus.CoordinatorNotRegistered.selector, v2CoordinatorAddr)); + vm.expectRevert(abi.encodeWithSelector(VRFCoordinatorV2_5.CoordinatorNotRegistered.selector, v2CoordinatorAddr)); v1Coordinator.migrate(subId, v2CoordinatorAddr); // test register/deregister multiple coordinators @@ -146,20 +146,20 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { function testMigration() public { linkToken.transferAndCall(v1CoordinatorAddr, DEFAULT_LINK_FUNDING, abi.encode(subId)); - v1Coordinator.fundSubscriptionWithEth{value: DEFAULT_NATIVE_FUNDING}(subId); + v1Coordinator.fundSubscriptionWithNative{value: DEFAULT_NATIVE_FUNDING}(subId); v1Coordinator.addConsumer(subId, address(testConsumer)); // subscription exists in V1 coordinator before migration - (uint96 balance, uint96 ethBalance, uint64 reqCount, address owner, address[] memory consumers) = v1Coordinator + (uint96 balance, uint96 nativeBalance, uint64 reqCount, address owner, address[] memory consumers) = v1Coordinator .getSubscription(subId); assertEq(balance, DEFAULT_LINK_FUNDING); - assertEq(ethBalance, DEFAULT_NATIVE_FUNDING); + assertEq(nativeBalance, DEFAULT_NATIVE_FUNDING); assertEq(owner, address(OWNER)); assertEq(consumers.length, 1); assertEq(consumers[0], address(testConsumer)); assertEq(v1Coordinator.s_totalBalance(), DEFAULT_LINK_FUNDING); - assertEq(v1Coordinator.s_totalEthBalance(), DEFAULT_NATIVE_FUNDING); + assertEq(v1Coordinator.s_totalNativeBalance(), DEFAULT_NATIVE_FUNDING); // Update consumer to point to the new coordinator vm.expectEmit( @@ -175,17 +175,18 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector); v1Coordinator.getSubscription(subId); assertEq(v1Coordinator.s_totalBalance(), 0); - assertEq(v1Coordinator.s_totalEthBalance(), 0); + assertEq(v1Coordinator.s_totalNativeBalance(), 0); assertEq(linkToken.balanceOf(v1CoordinatorAddr), 0); assertEq(v1CoordinatorAddr.balance, 0); // subscription exists in v2 coordinator - (owner, consumers, balance, ethBalance) = v2Coordinator.getSubscription(subId); + (balance, nativeBalance, reqCount, owner, consumers) = v2Coordinator.getSubscription(subId); assertEq(owner, address(OWNER)); assertEq(consumers.length, 1); assertEq(consumers[0], address(testConsumer)); + assertEq(reqCount, 0); assertEq(balance, DEFAULT_LINK_FUNDING); - assertEq(ethBalance, DEFAULT_NATIVE_FUNDING); + assertEq(nativeBalance, DEFAULT_NATIVE_FUNDING); assertEq(v2Coordinator.s_totalLinkBalance(), DEFAULT_LINK_FUNDING); assertEq(v2Coordinator.s_totalNativeBalance(), DEFAULT_NATIVE_FUNDING); assertEq(linkToken.balanceOf(v2CoordinatorAddr), DEFAULT_LINK_FUNDING); @@ -213,25 +214,25 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { } function testMigrationNoLink() public { - v1Coordinator_noLink.fundSubscriptionWithEth{value: DEFAULT_NATIVE_FUNDING}(subId_noLink); + v1Coordinator_noLink.fundSubscriptionWithNative{value: DEFAULT_NATIVE_FUNDING}(subId_noLink); v1Coordinator_noLink.addConsumer(subId_noLink, address(testConsumer_noLink)); // subscription exists in V1 coordinator before migration ( uint96 balance, - uint96 ethBalance, + uint96 nativeBalance, uint64 reqCount, address owner, address[] memory consumers ) = v1Coordinator_noLink.getSubscription(subId_noLink); assertEq(balance, 0); - assertEq(ethBalance, DEFAULT_NATIVE_FUNDING); + assertEq(nativeBalance, DEFAULT_NATIVE_FUNDING); assertEq(owner, address(OWNER)); assertEq(consumers.length, 1); assertEq(consumers[0], address(testConsumer_noLink)); assertEq(v1Coordinator_noLink.s_totalBalance(), 0); - assertEq(v1Coordinator_noLink.s_totalEthBalance(), DEFAULT_NATIVE_FUNDING); + assertEq(v1Coordinator_noLink.s_totalNativeBalance(), DEFAULT_NATIVE_FUNDING); // Update consumer to point to the new coordinator vm.expectEmit( @@ -247,17 +248,18 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector); v1Coordinator_noLink.getSubscription(subId); assertEq(v1Coordinator_noLink.s_totalBalance(), 0); - assertEq(v1Coordinator_noLink.s_totalEthBalance(), 0); + assertEq(v1Coordinator_noLink.s_totalNativeBalance(), 0); assertEq(linkToken.balanceOf(v1CoordinatorAddr_noLink), 0); assertEq(v1CoordinatorAddr_noLink.balance, 0); // subscription exists in v2 coordinator - (owner, consumers, balance, ethBalance) = v2Coordinator_noLink.getSubscription(subId_noLink); + (balance, nativeBalance, reqCount, owner, consumers) = v2Coordinator_noLink.getSubscription(subId_noLink); assertEq(owner, address(OWNER)); assertEq(consumers.length, 1); assertEq(consumers[0], address(testConsumer_noLink)); + assertEq(reqCount, 0); assertEq(balance, 0); - assertEq(ethBalance, DEFAULT_NATIVE_FUNDING); + assertEq(nativeBalance, DEFAULT_NATIVE_FUNDING); assertEq(v2Coordinator_noLink.s_totalLinkBalance(), 0); assertEq(v2Coordinator_noLink.s_totalNativeBalance(), DEFAULT_NATIVE_FUNDING); assertEq(linkToken.balanceOf(v2CoordinatorAddr_noLink), 0); @@ -288,7 +290,7 @@ contract VRFCoordinatorV2Plus_Migration is BaseTest { address invalidCoordinator = makeAddr("invalidCoordinator"); vm.expectRevert( - abi.encodeWithSelector(VRFCoordinatorV2Plus.CoordinatorNotRegistered.selector, address(invalidCoordinator)) + abi.encodeWithSelector(VRFCoordinatorV2_5.CoordinatorNotRegistered.selector, address(invalidCoordinator)) ); v1Coordinator.migrate(subId, invalidCoordinator); } diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol index 9eb3550a8f..13d52b676c 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFV2Plus.t.sol @@ -4,8 +4,8 @@ import "../BaseTest.t.sol"; import {VRF} from "../../../../src/v0.8/vrf/VRF.sol"; import {MockLinkToken} from "../../../../src/v0.8/mocks/MockLinkToken.sol"; import {MockV3Aggregator} from "../../../../src/v0.8/tests/MockV3Aggregator.sol"; -import {ExposedVRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol"; -import {VRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol"; +import {ExposedVRFCoordinatorV2_5} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol"; +import {VRFCoordinatorV2_5} from "../../../../src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol"; import {SubscriptionAPI} from "../../../../src/v0.8/dev/vrf/SubscriptionAPI.sol"; import {BlockhashStore} from "../../../../src/v0.8/dev/BlockhashStore.sol"; import {VRFV2PlusConsumerExample} from "../../../../src/v0.8/dev/vrf/testhelpers/VRFV2PlusConsumerExample.sol"; @@ -31,14 +31,14 @@ contract VRFV2Plus is BaseTest { hex"60806040523480156200001157600080fd5b5060405162001377380380620013778339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060038054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b61116380620002146000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638098004311610097578063cf62c8ab11610066578063cf62c8ab14610242578063de367c8e14610255578063eff2701714610268578063f2fde38b1461027b57600080fd5b806380980043146101ab5780638da5cb5b146101be5780638ea98117146101cf578063a168fa89146101e257600080fd5b80635d7d53e3116100d35780635d7d53e314610166578063706da1ca1461016f5780637725135b1461017857806379ba5097146101a357600080fd5b80631fe543e31461010557806329e5d8311461011a5780632fa4e4421461014057806336bfffed14610153575b600080fd5b610118610113366004610e4e565b61028e565b005b61012d610128366004610ef2565b6102fa565b6040519081526020015b60405180910390f35b61011861014e366004610f7f565b610410565b610118610161366004610d5b565b6104bc565b61012d60045481565b61012d60065481565b60035461018b906001600160a01b031681565b6040516001600160a01b039091168152602001610137565b6101186105c0565b6101186101b9366004610e1c565b600655565b6000546001600160a01b031661018b565b6101186101dd366004610d39565b61067e565b61021d6101f0366004610e1c565b6007602052600090815260409020805460019091015460ff82169161010090046001600160a01b03169083565b6040805193151584526001600160a01b03909216602084015290820152606001610137565b610118610250366004610f7f565b61073d565b60055461018b906001600160a01b031681565b610118610276366004610f14565b610880565b610118610289366004610d39565b610a51565b6002546001600160a01b031633146102ec576002546040517f1cf993f40000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6102f68282610a65565b5050565b60008281526007602090815260408083208151608081018352815460ff81161515825261010090046001600160a01b0316818501526001820154818401526002820180548451818702810187019095528085528695929460608601939092919083018282801561038957602002820191906000526020600020905b815481526020019060010190808311610375575b50505050508152505090508060400151600014156103e95760405162461bcd60e51b815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016102e3565b806060015183815181106103ff576103ff61111c565b602002602001015191505092915050565b6003546002546006546040805160208101929092526001600160a01b0393841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b815260040161046a93929190610ffa565b602060405180830381600087803b15801561048457600080fd5b505af1158015610498573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102f69190610dff565b60065461050b5760405162461bcd60e51b815260206004820152600d60248201527f7375624944206e6f74207365740000000000000000000000000000000000000060448201526064016102e3565b60005b81518110156102f65760055460065483516001600160a01b039092169163bec4c08c91908590859081106105445761054461111c565b60200260200101516040518363ffffffff1660e01b815260040161057b9291909182526001600160a01b0316602082015260400190565b600060405180830381600087803b15801561059557600080fd5b505af11580156105a9573d6000803e3d6000fd5b5050505080806105b8906110f3565b91505061050e565b6001546001600160a01b0316331461061a5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016102e3565b600080543373ffffffffffffffffffffffffffffffffffffffff19808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000546001600160a01b031633148015906106a457506002546001600160a01b03163314155b1561070e57336106bc6000546001600160a01b031690565b6002546040517f061db9c10000000000000000000000000000000000000000000000000000000081526001600160a01b03938416600482015291831660248301529190911660448201526064016102e3565b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b60065461041057600560009054906101000a90046001600160a01b03166001600160a01b031663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561079457600080fd5b505af11580156107a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107cc9190610e35565b60068190556005546040517fbec4c08c00000000000000000000000000000000000000000000000000000000815260048101929092523060248301526001600160a01b03169063bec4c08c90604401600060405180830381600087803b15801561083557600080fd5b505af1158015610849573d6000803e3d6000fd5b505050506003546002546006546040516001600160a01b0393841693634000aea0931691859161043d919060200190815260200190565b60006040518060c0016040528084815260200160065481526020018661ffff1681526020018763ffffffff1681526020018563ffffffff1681526020016108d66040518060200160405280861515815250610af8565b90526002546040517f9b1c385e0000000000000000000000000000000000000000000000000000000081529192506000916001600160a01b0390911690639b1c385e90610927908590600401611039565b602060405180830381600087803b15801561094157600080fd5b505af1158015610955573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109799190610e35565b604080516080810182526000808252336020808401918252838501868152855184815280830187526060860190815287855260078352959093208451815493517fffffffffffffffffffffff0000000000000000000000000000000000000000009094169015157fffffffffffffffffffffff0000000000000000000000000000000000000000ff16176101006001600160a01b039094169390930292909217825591516001820155925180519495509193849392610a3f926002850192910190610ca9565b50505060049190915550505050505050565b610a59610b96565b610a6281610bf2565b50565b6004548214610ab65760405162461bcd60e51b815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016102e3565b60008281526007602090815260409091208251610adb92600290920191840190610ca9565b50506000908152600760205260409020805460ff19166001179055565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610b3191511515815260200190565b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b6000546001600160a01b03163314610bf05760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102e3565b565b6001600160a01b038116331415610c4b5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102e3565b6001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610ce4579160200282015b82811115610ce4578251825591602001919060010190610cc9565b50610cf0929150610cf4565b5090565b5b80821115610cf05760008155600101610cf5565b80356001600160a01b0381168114610d2057600080fd5b919050565b803563ffffffff81168114610d2057600080fd5b600060208284031215610d4b57600080fd5b610d5482610d09565b9392505050565b60006020808385031215610d6e57600080fd5b823567ffffffffffffffff811115610d8557600080fd5b8301601f81018513610d9657600080fd5b8035610da9610da4826110cf565b61109e565b80828252848201915084840188868560051b8701011115610dc957600080fd5b600094505b83851015610df357610ddf81610d09565b835260019490940193918501918501610dce565b50979650505050505050565b600060208284031215610e1157600080fd5b8151610d5481611148565b600060208284031215610e2e57600080fd5b5035919050565b600060208284031215610e4757600080fd5b5051919050565b60008060408385031215610e6157600080fd5b8235915060208084013567ffffffffffffffff811115610e8057600080fd5b8401601f81018613610e9157600080fd5b8035610e9f610da4826110cf565b80828252848201915084840189868560051b8701011115610ebf57600080fd5b600094505b83851015610ee2578035835260019490940193918501918501610ec4565b5080955050505050509250929050565b60008060408385031215610f0557600080fd5b50508035926020909101359150565b600080600080600060a08688031215610f2c57600080fd5b610f3586610d25565b9450602086013561ffff81168114610f4c57600080fd5b9350610f5a60408701610d25565b9250606086013591506080860135610f7181611148565b809150509295509295909350565b600060208284031215610f9157600080fd5b81356bffffffffffffffffffffffff81168114610d5457600080fd5b6000815180845260005b81811015610fd357602081850181015186830182015201610fb7565b81811115610fe5576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b03841681526bffffffffffffffffffffffff831660208201526060604082015260006110306060830184610fad565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261109660e0840182610fad565b949350505050565b604051601f8201601f1916810167ffffffffffffffff811182821017156110c7576110c7611132565b604052919050565b600067ffffffffffffffff8211156110e9576110e9611132565b5060051b60200190565b600060001982141561111557634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b8015158114610a6257600080fdfea164736f6c6343000806000a"; BlockhashStore s_bhs; - ExposedVRFCoordinatorV2Plus s_testCoordinator; - ExposedVRFCoordinatorV2Plus s_testCoordinator_noLink; + ExposedVRFCoordinatorV2_5 s_testCoordinator; + ExposedVRFCoordinatorV2_5 s_testCoordinator_noLink; VRFV2PlusConsumerExample s_testConsumer; MockLinkToken s_linkToken; - MockV3Aggregator s_linkEthFeed; + MockV3Aggregator s_linkNativeFeed; - VRFCoordinatorV2Plus.FeeConfig basicFeeConfig = - VRFCoordinatorV2Plus.FeeConfig({fulfillmentFlatFeeLinkPPM: 0, fulfillmentFlatFeeEthPPM: 0}); + VRFCoordinatorV2_5.FeeConfig basicFeeConfig = + VRFCoordinatorV2_5.FeeConfig({fulfillmentFlatFeeLinkPPM: 0, fulfillmentFlatFeeNativePPM: 0}); // VRF KeyV2 generated from a node; not sensitive information. // The secret key used to generate this key is: 10. @@ -60,9 +60,9 @@ contract VRFV2Plus is BaseTest { // Deploy coordinator and consumer. // Note: adding contract deployments to this section will require the VRF proofs be regenerated. - s_testCoordinator = new ExposedVRFCoordinatorV2Plus(address(s_bhs)); + s_testCoordinator = new ExposedVRFCoordinatorV2_5(address(s_bhs)); s_linkToken = new MockLinkToken(); - s_linkEthFeed = new MockV3Aggregator(18, 500000000000000000); // .5 ETH (good for testing) + s_linkNativeFeed = new MockV3Aggregator(18, 500000000000000000); // .5 ETH (good for testing) // Use create2 to deploy our consumer, so that its address is always the same // and surrounding changes do not alter our generated proofs. @@ -82,13 +82,13 @@ contract VRFV2Plus is BaseTest { } s_testConsumer = VRFV2PlusConsumerExample(consumerCreate2Address); - s_testCoordinator_noLink = new ExposedVRFCoordinatorV2Plus(address(s_bhs)); + s_testCoordinator_noLink = new ExposedVRFCoordinatorV2_5(address(s_bhs)); // Configure the coordinator. - s_testCoordinator.setLINKAndLINKETHFeed(address(s_linkToken), address(s_linkEthFeed)); + s_testCoordinator.setLINKAndLINKNativeFeed(address(s_linkToken), address(s_linkNativeFeed)); } - function setConfig(VRFCoordinatorV2Plus.FeeConfig memory feeConfig) internal { + function setConfig(VRFCoordinatorV2_5.FeeConfig memory feeConfig) internal { s_testCoordinator.setConfig( 0, // minRequestConfirmations 2_500_000, // maxGasLimit @@ -107,11 +107,11 @@ contract VRFV2Plus is BaseTest { assertEq(gasLimit, 2_500_000); // Test that setting requestConfirmations above MAX_REQUEST_CONFIRMATIONS reverts. - vm.expectRevert(abi.encodeWithSelector(VRFCoordinatorV2Plus.InvalidRequestConfirmations.selector, 500, 500, 200)); + vm.expectRevert(abi.encodeWithSelector(VRFCoordinatorV2_5.InvalidRequestConfirmations.selector, 500, 500, 200)); s_testCoordinator.setConfig(500, 2_500_000, 1, 50_000, 50000000000000000, basicFeeConfig); // Test that setting fallbackWeiPerUnitLink to zero reverts. - vm.expectRevert(abi.encodeWithSelector(VRFCoordinatorV2Plus.InvalidLinkWeiPrice.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(VRFCoordinatorV2_5.InvalidLinkWeiPrice.selector, 0)); s_testCoordinator.setConfig(0, 2_500_000, 1, 50_000, 0, basicFeeConfig); } @@ -123,7 +123,7 @@ contract VRFV2Plus is BaseTest { // Should revert when already registered. uint256[2] memory uncompressedKeyParts = this.getProvingKeyParts(vrfUncompressedPublicKey); - vm.expectRevert(abi.encodeWithSelector(VRFCoordinatorV2Plus.ProvingKeyAlreadyRegistered.selector, vrfKeyHash)); + vm.expectRevert(abi.encodeWithSelector(VRFCoordinatorV2_5.ProvingKeyAlreadyRegistered.selector, vrfKeyHash)); s_testCoordinator.registerProvingKey(LINK_WHALE, uncompressedKeyParts); } @@ -142,12 +142,12 @@ contract VRFV2Plus is BaseTest { function testCreateSubscription() public { uint256 subId = s_testCoordinator.createSubscription(); - s_testCoordinator.fundSubscriptionWithEth{value: 10 ether}(subId); + s_testCoordinator.fundSubscriptionWithNative{value: 10 ether}(subId); } function testCancelSubWithNoLink() public { uint256 subId = s_testCoordinator_noLink.createSubscription(); - s_testCoordinator_noLink.fundSubscriptionWithEth{value: 1000 ether}(subId); + s_testCoordinator_noLink.fundSubscriptionWithNative{value: 1000 ether}(subId); assertEq(LINK_WHALE.balance, 9000 ether); s_testCoordinator_noLink.cancelSubscription(subId, LINK_WHALE); @@ -204,7 +204,7 @@ contract VRFV2Plus is BaseTest { } function paginateSubscriptions( - ExposedVRFCoordinatorV2Plus coordinator, + ExposedVRFCoordinatorV2_5 coordinator, uint256 batchSize ) internal view returns (uint256[][] memory) { uint arrIndex = 0; @@ -244,7 +244,7 @@ contract VRFV2Plus is BaseTest { vm.roll(requestBlock); s_testConsumer.createSubscriptionAndFund(0); uint256 subId = s_testConsumer.s_subId(); - s_testCoordinator.fundSubscriptionWithEth{value: 10 ether}(subId); + s_testCoordinator.fundSubscriptionWithNative{value: 10 ether}(subId); // Apply basic configs to contract. setConfig(basicFeeConfig); @@ -318,7 +318,7 @@ contract VRFV2Plus is BaseTest { ], zInv: 92231836131549905872346812799402691650433126386650679876913933650318463342041 }); - VRFCoordinatorV2Plus.RequestCommitment memory rc = VRFCoordinatorV2Plus.RequestCommitment({ + VRFCoordinatorV2_5.RequestCommitment memory rc = VRFCoordinatorV2_5.RequestCommitment({ blockNum: requestBlock, subId: subId, callbackGasLimit: 1_000_000, @@ -326,7 +326,7 @@ contract VRFV2Plus is BaseTest { sender: address(s_testConsumer), extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: true})) }); - (, uint96 ethBalanceBefore, , , ) = s_testCoordinator.getSubscription(subId); + (, uint96 nativeBalanceBefore, , , ) = s_testCoordinator.getSubscription(subId); uint256 outputSeed = s_testCoordinator.getRandomnessFromProofExternal(proof, rc).randomness; vm.recordLogs(); @@ -352,8 +352,8 @@ contract VRFV2Plus is BaseTest { // billed_fee = baseFeeWei + flatFeeWei + l1CostWei // billed_fee = baseFeeWei + 0 + 0 // billed_fee = 150_000 - (, uint96 ethBalanceAfter, , , ) = s_testCoordinator.getSubscription(subId); - assertApproxEqAbs(ethBalanceAfter, ethBalanceBefore - 120_000, 10_000); + (, uint96 nativeBalanceAfter, , , ) = s_testCoordinator.getSubscription(subId); + assertApproxEqAbs(nativeBalanceAfter, nativeBalanceBefore - 120_000, 10_000); } function testRequestAndFulfillRandomWordsLINK() public { @@ -434,7 +434,7 @@ contract VRFV2Plus is BaseTest { ], zInv: 37397948970756055003892765560695914630264479979131589134478580629419519112029 }); - VRFCoordinatorV2Plus.RequestCommitment memory rc = VRFCoordinatorV2Plus.RequestCommitment({ + VRFCoordinatorV2_5.RequestCommitment memory rc = VRFCoordinatorV2_5.RequestCommitment({ blockNum: requestBlock, subId: subId, callbackGasLimit: 1000000, @@ -462,14 +462,14 @@ contract VRFV2Plus is BaseTest { // gasAfterPaymentCalculation is 50_000. // // The cost of the VRF fulfillment charged to the user is: - // paymentNoFee = (weiPerUnitGas * (gasAfterPaymentCalculation + startGas - gasleft() + l1CostWei) / link_eth_ratio) + // paymentNoFee = (weiPerUnitGas * (gasAfterPaymentCalculation + startGas - gasleft() + l1CostWei) / link_native_ratio) // paymentNoFee = (1 * (50_000 + 90_000 + 0)) / .5 // paymentNoFee = 280_000 // ... // billed_fee = paymentNoFee + fulfillmentFlatFeeLinkPPM // 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 + // note: delta is doubled from the native test to account for more variance due to the link/native ratio (uint96 linkBalanceAfter, , , , ) = s_testCoordinator.getSubscription(subId); assertApproxEqAbs(linkBalanceAfter, linkBalanceBefore - 280_000, 20_000); } diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2PlusSubscriptionAPI.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2PlusSubscriptionAPI.t.sol index 813b3d4c80..db9e11e059 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFV2PlusSubscriptionAPI.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFV2PlusSubscriptionAPI.t.sol @@ -1,7 +1,7 @@ pragma solidity 0.8.6; import "../BaseTest.t.sol"; -import {ExposedVRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol"; +import {ExposedVRFCoordinatorV2_5} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol"; import {SubscriptionAPI} from "../../../../src/v0.8/dev/vrf/SubscriptionAPI.sol"; import {MockLinkToken} from "../../../../src/v0.8/mocks/MockLinkToken.sol"; import {MockV3Aggregator} from "../../../../src/v0.8/tests/MockV3Aggregator.sol"; @@ -9,41 +9,41 @@ import "@openzeppelin/contracts/utils/Strings.sol"; // for Strings.toString contract VRFV2PlusSubscriptionAPITest is BaseTest { event SubscriptionFunded(uint256 indexed subId, uint256 oldBalance, uint256 newBalance); - event SubscriptionFundedWithEth(uint256 indexed subId, uint256 oldEthBalance, uint256 newEthBalance); - event SubscriptionCanceled(uint256 indexed subId, address to, uint256 amountLink, uint256 amountEth); + event SubscriptionFundedWithNative(uint256 indexed subId, uint256 oldNativeBalance, uint256 newNativeBalance); + event SubscriptionCanceled(uint256 indexed subId, address to, uint256 amountLink, uint256 amountNative); event FundsRecovered(address to, uint256 amountLink); - event EthFundsRecovered(address to, uint256 amountEth); + event NativeFundsRecovered(address to, uint256 amountNative); event SubscriptionOwnerTransferRequested(uint256 indexed subId, address from, address to); event SubscriptionOwnerTransferred(uint256 indexed subId, address from, address to); event SubscriptionConsumerAdded(uint256 indexed subId, address consumer); - ExposedVRFCoordinatorV2Plus s_subscriptionAPI; + ExposedVRFCoordinatorV2_5 s_subscriptionAPI; function setUp() public override { BaseTest.setUp(); address bhs = makeAddr("bhs"); - s_subscriptionAPI = new ExposedVRFCoordinatorV2Plus(bhs); + s_subscriptionAPI = new ExposedVRFCoordinatorV2_5(bhs); } function testDefaultState() public { assertEq(address(s_subscriptionAPI.LINK()), address(0)); - assertEq(address(s_subscriptionAPI.LINK_ETH_FEED()), address(0)); + assertEq(address(s_subscriptionAPI.LINK_NATIVE_FEED()), address(0)); assertEq(s_subscriptionAPI.s_currentSubNonce(), 0); assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 0); assertEq(s_subscriptionAPI.s_totalBalance(), 0); - assertEq(s_subscriptionAPI.s_totalEthBalance(), 0); + assertEq(s_subscriptionAPI.s_totalNativeBalance(), 0); } - function testSetLINKAndLINKETHFeed() public { + function testSetLINKAndLINKNativeFeed() public { address link = makeAddr("link"); - address linkEthFeed = makeAddr("linkEthFeed"); - s_subscriptionAPI.setLINKAndLINKETHFeed(link, linkEthFeed); + address linkNativeFeed = makeAddr("linkNativeFeed"); + s_subscriptionAPI.setLINKAndLINKNativeFeed(link, linkNativeFeed); assertEq(address(s_subscriptionAPI.LINK()), link); - assertEq(address(s_subscriptionAPI.LINK_ETH_FEED()), linkEthFeed); + assertEq(address(s_subscriptionAPI.LINK_NATIVE_FEED()), linkNativeFeed); // try setting it again, should revert vm.expectRevert(SubscriptionAPI.LinkAlreadySet.selector); - s_subscriptionAPI.setLINKAndLINKETHFeed(link, linkEthFeed); + s_subscriptionAPI.setLINKAndLINKNativeFeed(link, linkNativeFeed); } function testOwnerCancelSubscriptionNoFunds() public { @@ -88,8 +88,8 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // fund the subscription with ether vm.deal(subOwner, 10 ether); vm.expectEmit(true, false, false, true); - emit SubscriptionFundedWithEth(subId, 0, 5 ether); - s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + emit SubscriptionFundedWithNative(subId, 0, 5 ether); + s_subscriptionAPI.fundSubscriptionWithNative{value: 5 ether}(subId); // change back to owner and cancel the subscription changePrank(OWNER); @@ -100,9 +100,9 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // assert that the subscription no longer exists assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 0); assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, address(0)); - assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).ethBalance, 0); + assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).nativeBalance, 0); - // check the ether balance of the subOwner, should be 10 ether + // check the native balance of the subOwner, should be 10 ether assertEq(address(subOwner).balance, 10 ether); } @@ -113,7 +113,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // Create link token and set the link token on the subscription api object MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // Create the subscription from a separate address @@ -151,7 +151,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // Create link token and set the link token on the subscription api object MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // Create the subscription from a separate address @@ -172,8 +172,8 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { vm.deal(subOwner, 10 ether); changePrank(subOwner); vm.expectEmit(true, false, false, true); - emit SubscriptionFundedWithEth(subId, 0, 5 ether); - s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + emit SubscriptionFundedWithNative(subId, 0, 5 ether); + s_subscriptionAPI.fundSubscriptionWithNative{value: 5 ether}(subId); // change back to owner and cancel the subscription changePrank(OWNER); @@ -185,12 +185,12 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { assertEq(s_subscriptionAPI.getActiveSubscriptionIdsLength(), 0); assertEq(s_subscriptionAPI.getSubscriptionConfig(subId).owner, address(0)); assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).balance, 0); - assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).ethBalance, 0); + assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).nativeBalance, 0); // check the link balance of the sub owner, should be 5 LINK assertEq(linkToken.balanceOf(subOwner), 5 ether, "link balance incorrect"); // check the ether balance of the sub owner, should be 10 ether - assertEq(address(subOwner).balance, 10 ether, "eth balance incorrect"); + assertEq(address(subOwner).balance, 10 ether, "native balance incorrect"); } function testRecoverFundsLINKNotSet() public { @@ -208,7 +208,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // Create link token and set the link token on the subscription api object MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // set the total balance to be greater than the external balance @@ -230,7 +230,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // Create link token and set the link token on the subscription api object MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // transfer 10 LINK to the contract to recover @@ -250,7 +250,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // Create link token and set the link token on the subscription api object MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // create a subscription and fund it with 5 LINK @@ -272,29 +272,29 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { assertEq(linkToken.balanceOf(address(s_subscriptionAPI)), s_subscriptionAPI.s_totalBalance()); } - function testRecoverEthFundsBalanceInvariantViolated() public { + function testRecoverNativeFundsBalanceInvariantViolated() public { // set the total balance to be greater than the external balance // so that we trigger the invariant violation // note that this field is not modifiable in the actual contracts // other than through onTokenTransfer or similar functions - s_subscriptionAPI.setTotalEthBalanceTestingOnlyXXX(100 ether); + s_subscriptionAPI.setTotalNativeBalanceTestingOnlyXXX(100 ether); // call recoverFunds vm.expectRevert(abi.encodeWithSelector(SubscriptionAPI.BalanceInvariantViolated.selector, 100 ether, 0)); - s_subscriptionAPI.recoverEthFunds(payable(OWNER)); + s_subscriptionAPI.recoverNativeFunds(payable(OWNER)); } - function testRecoverEthFundsAmountToTransfer() public { + function testRecoverNativeFundsAmountToTransfer() public { // transfer 10 LINK to the contract to recover vm.deal(address(s_subscriptionAPI), 10 ether); // call recoverFunds vm.expectEmit(true, false, false, true); - emit EthFundsRecovered(OWNER, 10 ether); - s_subscriptionAPI.recoverEthFunds(payable(OWNER)); + emit NativeFundsRecovered(OWNER, 10 ether); + s_subscriptionAPI.recoverNativeFunds(payable(OWNER)); } - function testRecoverEthFundsNothingToTransfer() public { + function testRecoverNativeFundsNothingToTransfer() public { // create a subscription and fund it with 5 ether address subOwner = makeAddr("subOwner"); changePrank(subOwner); @@ -306,13 +306,13 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { vm.deal(subOwner, 5 ether); changePrank(subOwner); vm.expectEmit(true, false, false, true); - emit SubscriptionFundedWithEth(subId, 0, 5 ether); - s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + emit SubscriptionFundedWithNative(subId, 0, 5 ether); + s_subscriptionAPI.fundSubscriptionWithNative{value: 5 ether}(subId); - // call recoverEthFunds, nothing should happen because external balance == internal balance + // call recoverNativeFunds, nothing should happen because external balance == internal balance changePrank(OWNER); - s_subscriptionAPI.recoverEthFunds(payable(OWNER)); - assertEq(address(s_subscriptionAPI).balance, s_subscriptionAPI.s_totalEthBalance()); + s_subscriptionAPI.recoverNativeFunds(payable(OWNER)); + assertEq(address(s_subscriptionAPI).balance, s_subscriptionAPI.s_totalNativeBalance()); } function testOracleWithdrawNoLink() public { @@ -325,7 +325,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // CASE: link token set, trying to withdraw // more than balance MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // call oracleWithdraw @@ -337,7 +337,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // CASE: link token set, trying to withdraw // less than balance MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // transfer 10 LINK to the contract to withdraw @@ -364,16 +364,16 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { assertEq(s_subscriptionAPI.s_totalBalance(), 9 ether, "total balance incorrect"); } - function testOracleWithdrawEthInsufficientBalance() public { + function testOracleWithdrawNativeInsufficientBalance() public { // CASE: trying to withdraw more than balance // should revert with InsufficientBalance - // call oracleWithdrawEth + // call oracleWithdrawNative vm.expectRevert(SubscriptionAPI.InsufficientBalance.selector); - s_subscriptionAPI.oracleWithdrawEth(payable(OWNER), 1 ether); + s_subscriptionAPI.oracleWithdrawNative(payable(OWNER), 1 ether); } - function testOracleWithdrawEthSufficientBalance() public { + function testOracleWithdrawNativeSufficientBalance() public { // CASE: trying to withdraw less than balance // should withdraw successfully @@ -382,22 +382,22 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // set the withdrawable eth of the oracle to be 1 ether address oracle = makeAddr("oracle"); - s_subscriptionAPI.setWithdrawableEthTestingOnlyXXX(oracle, 1 ether); - assertEq(s_subscriptionAPI.getWithdrawableEthTestingOnlyXXX(oracle), 1 ether); + s_subscriptionAPI.setWithdrawableNativeTestingOnlyXXX(oracle, 1 ether); + assertEq(s_subscriptionAPI.getWithdrawableNativeTestingOnlyXXX(oracle), 1 ether); // set the total balance to be the same as the eth balance for consistency // (this is not necessary for the test, but just to be sane) - s_subscriptionAPI.setTotalEthBalanceTestingOnlyXXX(10 ether); + s_subscriptionAPI.setTotalNativeBalanceTestingOnlyXXX(10 ether); - // call oracleWithdrawEth from oracle address + // call oracleWithdrawNative from oracle address changePrank(oracle); - s_subscriptionAPI.oracleWithdrawEth(payable(oracle), 1 ether); - // assert eth balance of oracle - assertEq(address(oracle).balance, 1 ether, "oracle eth balance incorrect"); + s_subscriptionAPI.oracleWithdrawNative(payable(oracle), 1 ether); + // assert native balance of oracle + assertEq(address(oracle).balance, 1 ether, "oracle native balance incorrect"); // assert state of subscription api - assertEq(s_subscriptionAPI.getWithdrawableEthTestingOnlyXXX(oracle), 0, "oracle withdrawable eth incorrect"); + assertEq(s_subscriptionAPI.getWithdrawableNativeTestingOnlyXXX(oracle), 0, "oracle withdrawable native incorrect"); // assert that total balance is changed by the withdrawn amount - assertEq(s_subscriptionAPI.s_totalEthBalance(), 9 ether, "total eth balance incorrect"); + assertEq(s_subscriptionAPI.s_totalNativeBalance(), 9 ether, "total native balance incorrect"); } function testOnTokenTransferCallerNotLink() public { @@ -408,7 +408,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { function testOnTokenTransferInvalidCalldata() public { // create and set link token on subscription api MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // call link.transferAndCall with invalid calldata @@ -419,7 +419,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { function testOnTokenTransferInvalidSubscriptionId() public { // create and set link token on subscription api MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // generate bogus sub id @@ -434,7 +434,7 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { // happy path link funding test // create and set link token on subscription api MockLinkToken linkToken = new MockLinkToken(); - s_subscriptionAPI.setLINKAndLINKETHFeed(address(linkToken), address(0)); + s_subscriptionAPI.setLINKAndLINKNativeFeed(address(linkToken), address(0)); assertEq(address(s_subscriptionAPI.LINK()), address(linkToken)); // create a subscription and fund it with 5 LINK @@ -455,40 +455,40 @@ contract VRFV2PlusSubscriptionAPITest is BaseTest { assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).balance, 5 ether); } - function testFundSubscriptionWithEthInvalidSubscriptionId() public { + function testFundSubscriptionWithNativeInvalidSubscriptionId() public { // CASE: invalid subscription id // should revert with InvalidSubscription uint256 subId = uint256(keccak256("idontexist")); - // try to fund the subscription with ether, should fail + // try to fund the subscription with native, should fail address funder = makeAddr("funder"); vm.deal(funder, 5 ether); changePrank(funder); vm.expectRevert(SubscriptionAPI.InvalidSubscription.selector); - s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + s_subscriptionAPI.fundSubscriptionWithNative{value: 5 ether}(subId); } - function testFundSubscriptionWithEth() public { + function testFundSubscriptionWithNative() public { // happy path test - // funding subscription with ether + // funding subscription with native - // create a subscription and fund it with ether + // create a subscription and fund it with native address subOwner = makeAddr("subOwner"); changePrank(subOwner); uint64 nonceBefore = s_subscriptionAPI.s_currentSubNonce(); uint256 subId = s_subscriptionAPI.createSubscription(); assertEq(s_subscriptionAPI.s_currentSubNonce(), nonceBefore + 1); - // fund the subscription with ether + // fund the subscription with native vm.deal(subOwner, 5 ether); changePrank(subOwner); vm.expectEmit(true, false, false, true); - emit SubscriptionFundedWithEth(subId, 0, 5 ether); - s_subscriptionAPI.fundSubscriptionWithEth{value: 5 ether}(subId); + emit SubscriptionFundedWithNative(subId, 0, 5 ether); + s_subscriptionAPI.fundSubscriptionWithNative{value: 5 ether}(subId); // assert that the subscription is funded - assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).ethBalance, 5 ether); + assertEq(s_subscriptionAPI.getSubscriptionStruct(subId).nativeBalance, 5 ether); } function testCreateSubscription() public { diff --git a/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol index 33bc72998f..4cb02991da 100644 --- a/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol +++ b/contracts/test/v0.8/foundry/vrf/VRFV2Wrapper.t.sol @@ -4,10 +4,10 @@ import "../BaseTest.t.sol"; import {VRF} from "../../../../src/v0.8/vrf/VRF.sol"; import {MockLinkToken} from "../../../../src/v0.8/mocks/MockLinkToken.sol"; import {MockV3Aggregator} from "../../../../src/v0.8/tests/MockV3Aggregator.sol"; -import {ExposedVRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2Plus.sol"; +import {ExposedVRFCoordinatorV2_5} from "../../../../src/v0.8/dev/vrf/testhelpers/ExposedVRFCoordinatorV2_5.sol"; import {VRFV2PlusWrapperConsumerBase} from "../../../../src/v0.8/dev/vrf/VRFV2PlusWrapperConsumerBase.sol"; import {VRFV2PlusWrapperConsumerExample} from "../../../../src/v0.8/dev/vrf/testhelpers/VRFV2PlusWrapperConsumerExample.sol"; -import {VRFCoordinatorV2Plus} from "../../../../src/v0.8/dev/vrf/VRFCoordinatorV2Plus.sol"; +import {VRFCoordinatorV2_5} from "../../../../src/v0.8/dev/vrf/VRFCoordinatorV2_5.sol"; import {VRFV2PlusWrapper} from "../../../../src/v0.8/dev/vrf/VRFV2PlusWrapper.sol"; import {VRFV2PlusClient} from "../../../../src/v0.8/dev/vrf/libraries/VRFV2PlusClient.sol"; import {console} from "forge-std/console.sol"; @@ -18,14 +18,14 @@ contract VRFV2PlusWrapperTest is BaseTest { uint32 wrapperGasOverhead = 10_000; uint32 coordinatorGasOverhead = 20_000; - ExposedVRFCoordinatorV2Plus s_testCoordinator; + ExposedVRFCoordinatorV2_5 s_testCoordinator; MockLinkToken s_linkToken; - MockV3Aggregator s_linkEthFeed; + MockV3Aggregator s_linkNativeFeed; VRFV2PlusWrapper s_wrapper; VRFV2PlusWrapperConsumerExample s_consumer; - VRFCoordinatorV2Plus.FeeConfig basicFeeConfig = - VRFCoordinatorV2Plus.FeeConfig({fulfillmentFlatFeeLinkPPM: 0, fulfillmentFlatFeeEthPPM: 0}); + VRFCoordinatorV2_5.FeeConfig basicFeeConfig = + VRFCoordinatorV2_5.FeeConfig({fulfillmentFlatFeeLinkPPM: 0, fulfillmentFlatFeeNativePPM: 0}); function setUp() public override { BaseTest.setUp(); @@ -35,24 +35,24 @@ contract VRFV2PlusWrapperTest is BaseTest { vm.deal(LINK_WHALE, 10_000 ether); changePrank(LINK_WHALE); - // Deploy link token and link/eth feed. + // Deploy link token and link/native feed. s_linkToken = new MockLinkToken(); - s_linkEthFeed = new MockV3Aggregator(18, 500000000000000000); // .5 ETH (good for testing) + s_linkNativeFeed = new MockV3Aggregator(18, 500000000000000000); // .5 ETH (good for testing) // Deploy coordinator and consumer. - s_testCoordinator = new ExposedVRFCoordinatorV2Plus(address(0)); - s_wrapper = new VRFV2PlusWrapper(address(s_linkToken), address(s_linkEthFeed), address(s_testCoordinator)); + s_testCoordinator = new ExposedVRFCoordinatorV2_5(address(0)); + s_wrapper = new VRFV2PlusWrapper(address(s_linkToken), address(s_linkNativeFeed), address(s_testCoordinator)); s_consumer = new VRFV2PlusWrapperConsumerExample(address(s_linkToken), address(s_wrapper)); // Configure the coordinator. - s_testCoordinator.setLINKAndLINKETHFeed(address(s_linkToken), address(s_linkEthFeed)); + s_testCoordinator.setLINKAndLINKNativeFeed(address(s_linkToken), address(s_linkNativeFeed)); setConfigCoordinator(basicFeeConfig); setConfigWrapper(); s_testCoordinator.s_config(); } - function setConfigCoordinator(VRFCoordinatorV2Plus.FeeConfig memory feeConfig) internal { + function setConfigCoordinator(VRFCoordinatorV2_5.FeeConfig memory feeConfig) internal { s_testCoordinator.setConfig( 0, // minRequestConfirmations 2_500_000, // maxGasLimit @@ -69,7 +69,11 @@ contract VRFV2PlusWrapperTest is BaseTest { coordinatorGasOverhead, // coordinator gas overhead 0, // premium percentage vrfKeyHash, // keyHash - 10 // max number of words + 10, // max number of words, + 1, // stalenessSeconds + 50000000000000000, // fallbackWeiPerUnitLink + 0, // fulfillmentFlatFeeLinkPPM + 0 // fulfillmentFlatFeeNativePPM ); ( , @@ -100,14 +104,14 @@ contract VRFV2PlusWrapperTest is BaseTest { address indexed sender ); - function testSetLinkAndLinkEthFeed() public { + function testSetLinkAndLinkNativeFeed() public { VRFV2PlusWrapper wrapper = new VRFV2PlusWrapper(address(0), address(0), address(s_testCoordinator)); - // Set LINK and LINK/ETH feed on wrapper. + // Set LINK and LINK/Native feed on wrapper. wrapper.setLINK(address(s_linkToken)); - wrapper.setLinkEthFeed(address(s_linkEthFeed)); + wrapper.setLinkNativeFeed(address(s_linkNativeFeed)); assertEq(address(wrapper.s_link()), address(s_linkToken)); - assertEq(address(wrapper.s_linkEthFeed()), address(s_linkEthFeed)); + assertEq(address(wrapper.s_linkNativeFeed()), address(s_linkNativeFeed)); // Revert for subsequent assignment. vm.expectRevert(VRFV2PlusWrapper.LinkAlreadySet.selector); @@ -124,7 +128,7 @@ contract VRFV2PlusWrapperTest is BaseTest { function testRequestAndFulfillRandomWordsNativeWrapper() public { // Fund subscription. - s_testCoordinator.fundSubscriptionWithEth{value: 10 ether}(s_wrapper.SUBSCRIPTION_ID()); + s_testCoordinator.fundSubscriptionWithNative{value: 10 ether}(s_wrapper.SUBSCRIPTION_ID()); vm.deal(address(s_consumer), 10 ether); // Get type and version. @@ -222,7 +226,7 @@ contract VRFV2PlusWrapperTest is BaseTest { uint32 expectedPaid = (callbackGasLimit + wrapperGasOverhead + coordinatorGasOverhead) * 2; uint256 wrapperCostEstimate = s_wrapper.estimateRequestPrice(callbackGasLimit, tx.gasprice); uint256 wrapperCostCalculation = s_wrapper.calculateRequestPrice(callbackGasLimit); - assertEq(paid, expectedPaid); // 1_030_000 * 2 for link/eth ratio + assertEq(paid, expectedPaid); // 1_030_000 * 2 for link/native ratio assertEq(uint256(paid), wrapperCostEstimate); assertEq(wrapperCostEstimate, wrapperCostCalculation); assertEq(fulfilled, false); diff --git a/core/chainlink.Dockerfile b/core/chainlink.Dockerfile index 5daa4bf85c..be1fdb9053 100644 --- a/core/chainlink.Dockerfile +++ b/core/chainlink.Dockerfile @@ -1,5 +1,5 @@ # Build image: Chainlink binary -FROM golang:1.20-buster as buildgo +FROM golang:1.21-bullseye as buildgo RUN go version WORKDIR /chainlink diff --git a/core/chainlink.devspace.Dockerfile b/core/chainlink.devspace.Dockerfile index e538f8c863..9ec061ae40 100644 --- a/core/chainlink.devspace.Dockerfile +++ b/core/chainlink.devspace.Dockerfile @@ -1,5 +1,5 @@ # Build image: Chainlink binary -FROM golang:1.20-buster as buildgo +FROM golang:1.21-bullseye as buildgo RUN go version WORKDIR /chainlink @@ -18,7 +18,7 @@ COPY . . RUN make install-chainlink # Final image: ubuntu with chainlink binary -FROM golang:1.20-buster +FROM golang:1.21-bullseye ARG CHAINLINK_USER=root ENV DEBIAN_FRONTEND noninteractive diff --git a/core/chains/evm/chain.go b/core/chains/evm/chain.go index 6a948a4cdd..b4986ad0c2 100644 --- a/core/chains/evm/chain.go +++ b/core/chains/evm/chain.go @@ -142,22 +142,34 @@ type AppConfig interface { type ChainRelayExtenderConfig struct { Logger logger.Logger - DB *sqlx.DB KeyStore keystore.Eth - *RelayerConfig + ChainOpts } -// 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 { +func (c ChainRelayExtenderConfig) Validate() error { + err := c.ChainOpts.Validate() + if c.Logger == nil { + err = errors.Join(err, errors.New("nil Logger")) + } + if c.KeyStore == nil { + err = errors.Join(err, errors.New("nil Keystore")) + } + + if err != nil { + err = fmt.Errorf("invalid ChainRelayerExtenderConfig: %w", err) + } + return err +} + +type ChainOpts struct { AppConfig AppConfig EventBroadcaster pg.EventBroadcaster MailMon *utils.MailboxMonitor GasEstimator gas.EvmFeeEstimator + *sqlx.DB + // TODO BCF-2513 remove test code from the API // Gen-functions are useful for dependency injection by tests GenEthClient func(*big.Int) client.Client @@ -168,7 +180,31 @@ type RelayerConfig struct { GenGasEstimator func(*big.Int) gas.EvmFeeEstimator } +func (o ChainOpts) Validate() error { + var err error + if o.AppConfig == nil { + err = errors.Join(err, errors.New("nil AppConfig")) + } + if o.EventBroadcaster == nil { + err = errors.Join(err, errors.New("nil EventBroadcaster")) + } + if o.MailMon == nil { + err = errors.Join(err, errors.New("nil MailMon")) + } + if o.DB == nil { + err = errors.Join(err, errors.New("nil DB")) + } + if err != nil { + err = fmt.Errorf("invalid ChainOpts: %w", err) + } + return err +} + func NewTOMLChain(ctx context.Context, chain *toml.EVMConfig, opts ChainRelayExtenderConfig) (Chain, error) { + err := opts.Validate() + if err != nil { + return nil, err + } chainID := chain.ChainID l := opts.Logger.With("evmChainID", chainID.String()) if !chain.IsEnabled() { @@ -214,7 +250,7 @@ func newChain(ctx context.Context, cfg *evmconfig.ChainScoped, nodes []*toml.Nod if opts.GenLogPoller != nil { logPoller = opts.GenLogPoller(chainID) } else { - logPoller = logpoller.NewObservedLogPoller(logpoller.NewORM(chainID, db, l, cfg.Database()), client, l, cfg.EVM().LogPollInterval(), int64(cfg.EVM().FinalityDepth()), int64(cfg.EVM().LogBackfillBatchSize()), int64(cfg.EVM().RPCDefaultBatchSize()), int64(cfg.EVM().LogKeepBlocksDepth())) + logPoller = logpoller.NewLogPoller(logpoller.NewObservedORM(chainID, db, l, cfg.Database()), client, l, cfg.EVM().LogPollInterval(), int64(cfg.EVM().FinalityDepth()), int64(cfg.EVM().LogBackfillBatchSize()), int64(cfg.EVM().RPCDefaultBatchSize()), int64(cfg.EVM().LogKeepBlocksDepth())) } } @@ -458,14 +494,3 @@ 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") - } - - return nil -} diff --git a/core/chains/evm/chain_test.go b/core/chains/evm/chain_test.go index 41f498b3e7..09395ff4c9 100644 --- a/core/chains/evm/chain_test.go +++ b/core/chains/evm/chain_test.go @@ -4,11 +4,15 @@ import ( "math/big" "testing" + "github.com/smartcontractkit/sqlx" "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/internal/testutils/pgtest" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) func TestLegacyChains(t *testing.T) { @@ -25,3 +29,50 @@ func TestLegacyChains(t *testing.T) { assert.Equal(t, c, got) } + +func TestChainOpts_Validate(t *testing.T) { + type fields struct { + AppConfig evm.AppConfig + EventBroadcaster pg.EventBroadcaster + MailMon *utils.MailboxMonitor + DB *sqlx.DB + } + tests := []struct { + name string + fields fields + wantErr bool + }{ + { + name: "valid", + fields: fields{ + AppConfig: configtest.NewTestGeneralConfig(t), + EventBroadcaster: pg.NewNullEventBroadcaster(), + MailMon: &utils.MailboxMonitor{}, + DB: pgtest.NewSqlxDB(t), + }, + }, + { + name: "invalid", + fields: fields{ + AppConfig: nil, + EventBroadcaster: nil, + MailMon: nil, + DB: nil, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + o := evm.ChainOpts{ + AppConfig: tt.fields.AppConfig, + EventBroadcaster: tt.fields.EventBroadcaster, + MailMon: tt.fields.MailMon, + DB: tt.fields.DB, + } + if err := o.Validate(); (err != nil) != tt.wantErr { + t.Errorf("ChainOpts.Validate() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/core/chains/evm/config/toml/config.go b/core/chains/evm/config/toml/config.go index a94e45ae89..a62c554a21 100644 --- a/core/chains/evm/config/toml/config.go +++ b/core/chains/evm/config/toml/config.go @@ -804,9 +804,5 @@ func (n *Node) SetFrom(f *Node) { } func ChainIDInt64(cid relay.ChainID) (int64, error) { - i, err := strconv.Atoi(cid) - if err != nil { - return int64(0), err - } - return int64(i), nil + return strconv.ParseInt(cid, 10, 64) } diff --git a/core/chains/evm/config/toml/defaults.go b/core/chains/evm/config/toml/defaults.go index 8c32b81301..239a97f585 100644 --- a/core/chains/evm/config/toml/defaults.go +++ b/core/chains/evm/config/toml/defaults.go @@ -164,7 +164,8 @@ func (c *Chain) SetFrom(f *Chain) { c.GasEstimator.setFrom(&f.GasEstimator) if ks := f.KeySpecific; ks != nil { - for _, v := range ks { + for i := range ks { + v := ks[i] if i := slices.IndexFunc(c.KeySpecific, func(k KeySpecific) bool { return k.Key == v.Key }); i == -1 { c.KeySpecific = append(c.KeySpecific, v) } else { diff --git a/core/chains/evm/logpoller/helper_test.go b/core/chains/evm/logpoller/helper_test.go index 4c764d7d74..447a467358 100644 --- a/core/chains/evm/logpoller/helper_test.go +++ b/core/chains/evm/logpoller/helper_test.go @@ -36,7 +36,7 @@ type TestHarness struct { Lggr logger.Logger // Chain2/ORM2 is just a dummy second chain, doesn't have a client. ChainID, ChainID2 *big.Int - ORM, ORM2 *logpoller.ORM + ORM, ORM2 *logpoller.DbORM LogPoller logpoller.LogPollerTest Client *backends.SimulatedBackend Owner *bind.TransactOpts diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index d6e5528602..f4b3a7f4f0 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -87,7 +87,7 @@ var ( type logPoller struct { utils.StartStopOnce ec Client - orm *ORM + orm ORM lggr logger.Logger pollPeriod time.Duration // poll period set by block production rate finalityDepth int64 // finality depth is taken to mean that block (head - finality) is finalized @@ -119,7 +119,7 @@ type logPoller struct { // // How fast that can be done depends largely on network speed and DB, but even for the fastest // support chain, polygon, which has 2s block times, we need RPCs roughly with <= 500ms latency -func NewLogPoller(orm *ORM, ec Client, lggr logger.Logger, pollPeriod time.Duration, +func NewLogPoller(orm ORM, ec Client, lggr logger.Logger, pollPeriod time.Duration, finalityDepth int64, backfillBatchSize int64, rpcBatchSize int64, keepBlocksDepth int64) *logPoller { return &logPoller{ @@ -676,7 +676,7 @@ func (lp *logPoller) backfill(ctx context.Context, start, end int64) error { } lp.lggr.Debugw("Backfill found logs", "from", from, "to", to, "logs", len(gethLogs), "blocks", blocks) - err = lp.orm.q.WithOpts(pg.WithParentCtx(ctx)).Transaction(func(tx pg.Queryer) error { + err = lp.orm.Q().WithOpts(pg.WithParentCtx(ctx)).Transaction(func(tx pg.Queryer) error { return lp.orm.InsertLogs(convertLogs(gethLogs, blocks, lp.lggr, lp.ec.ConfiguredChainID()), pg.WithQueryer(tx)) }) if err != nil { @@ -747,7 +747,7 @@ func (lp *logPoller) getCurrentBlockMaybeHandleReorg(ctx context.Context, curren // the canonical set per read. Typically, if an application took action on a log // it would be saved elsewhere e.g. evm.txes, so it seems better to just support the fast reads. // Its also nicely analogous to reading from the chain itself. - err2 = lp.orm.q.WithOpts(pg.WithParentCtx(ctx)).Transaction(func(tx pg.Queryer) error { + err2 = lp.orm.Q().WithOpts(pg.WithParentCtx(ctx)).Transaction(func(tx pg.Queryer) error { // These deletes are bounded by reorg depth, so they are // fast and should not slow down the log readers. err3 := lp.orm.DeleteBlocksAfter(blockAfterLCA.Number, pg.WithQueryer(tx)) @@ -844,7 +844,7 @@ func (lp *logPoller) PollAndSaveLogs(ctx context.Context, currentBlockNumber int return } lp.lggr.Debugw("Unfinalized log query", "logs", len(logs), "currentBlockNumber", currentBlockNumber, "blockHash", currentBlock.Hash, "timestamp", currentBlock.Timestamp.Unix()) - err = lp.orm.q.WithOpts(pg.WithParentCtx(ctx)).Transaction(func(tx pg.Queryer) error { + err = lp.orm.Q().WithOpts(pg.WithParentCtx(ctx)).Transaction(func(tx pg.Queryer) error { if err2 := lp.orm.InsertBlock(h, currentBlockNumber, currentBlock.Timestamp, pg.WithQueryer(tx)); err2 != nil { return err2 } @@ -937,15 +937,15 @@ func (lp *logPoller) pruneOldBlocks(ctx context.Context) error { // Logs returns logs matching topics and address (exactly) in the given block range, // which are canonical at time of query. func (lp *logPoller) Logs(start, end int64, eventSig common.Hash, address common.Address, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLogsByBlockRangeFilter(start, end, address, eventSig, qopts...) + return lp.orm.SelectLogs(start, end, address, eventSig, qopts...) } func (lp *logPoller) LogsWithSigs(start, end int64, eventSigs []common.Hash, address common.Address, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLogsWithSigsByBlockRangeFilter(start, end, address, eventSigs, qopts...) + return lp.orm.SelectLogsWithSigs(start, end, address, eventSigs, qopts...) } func (lp *logPoller) LogsCreatedAfter(eventSig common.Hash, address common.Address, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectLogsCreatedAfter(eventSig[:], address, after, confs, qopts...) + return lp.orm.SelectLogsCreatedAfter(address, eventSig, after, confs, qopts...) } // IndexedLogs finds all the logs that have a topic value in topicValues at index topicIndex. @@ -955,7 +955,7 @@ func (lp *logPoller) IndexedLogs(eventSig common.Hash, address common.Address, t // IndexedLogsByBlockRange finds all the logs that have a topic value in topicValues at index topicIndex within the block range func (lp *logPoller) IndexedLogsByBlockRange(start, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexedLogsByBlockRangeFilter(start, end, address, eventSig, topicIndex, topicValues, qopts...) + return lp.orm.SelectIndexedLogsByBlockRange(start, end, address, eventSig, topicIndex, topicValues, qopts...) } func (lp *logPoller) IndexedLogsCreatedAfter(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { @@ -968,28 +968,28 @@ func (lp *logPoller) IndexedLogsByTxHash(eventSig common.Hash, txHash common.Has // LogsDataWordGreaterThan note index is 0 based. func (lp *logPoller) LogsDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectDataWordGreaterThan(address, eventSig, wordIndex, wordValueMin, confs, qopts...) + return lp.orm.SelectLogsDataWordGreaterThan(address, eventSig, wordIndex, wordValueMin, confs, qopts...) } // LogsDataWordRange note index is 0 based. func (lp *logPoller) LogsDataWordRange(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin, wordValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectDataWordRange(address, eventSig, wordIndex, wordValueMin, wordValueMax, confs, qopts...) + return lp.orm.SelectLogsDataWordRange(address, eventSig, wordIndex, wordValueMin, wordValueMax, confs, qopts...) } // IndexedLogsTopicGreaterThan finds all the logs that have a topic value greater than topicValueMin at index topicIndex. // Only works for integer topics. func (lp *logPoller) IndexedLogsTopicGreaterThan(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexLogsTopicGreaterThan(address, eventSig, topicIndex, topicValueMin, confs, qopts...) + return lp.orm.SelectIndexedLogsTopicGreaterThan(address, eventSig, topicIndex, topicValueMin, confs, qopts...) } // LogsUntilBlockHashDataWordGreaterThan note index is 0 based. // If the blockhash is not found (i.e. a stale fork) it will error. func (lp *logPoller) LogsUntilBlockHashDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, untilBlockHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectUntilBlockHashDataWordGreaterThan(address, eventSig, wordIndex, wordValueMin, untilBlockHash, qopts...) + return lp.orm.SelectLogsUntilBlockHashDataWordGreaterThan(address, eventSig, wordIndex, wordValueMin, untilBlockHash, qopts...) } func (lp *logPoller) IndexedLogsTopicRange(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { - return lp.orm.SelectIndexLogsTopicRange(address, eventSig, topicIndex, topicValueMin, topicValueMax, confs, qopts...) + return lp.orm.SelectIndexedLogsTopicRange(address, eventSig, topicIndex, topicValueMin, topicValueMax, confs, qopts...) } // LatestBlock returns the latest block the log poller is on. It tracks blocks to be able @@ -1009,7 +1009,7 @@ func (lp *logPoller) BlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, // LatestLogByEventSigWithConfs finds the latest log that has confs number of blocks on top of the log. func (lp *logPoller) LatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs int, qopts ...pg.QOpt) (*Log, error) { - return lp.orm.SelectLatestLogEventSigWithConfs(eventSig, address, confs, qopts...) + return lp.orm.SelectLatestLogByEventSigWithConfs(eventSig, address, confs, qopts...) } func (lp *logPoller) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) ([]Log, error) { @@ -1017,7 +1017,7 @@ func (lp *logPoller) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs } 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...) + return lp.orm.SelectLatestBlockByEventSigsAddrsWithConfs(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 5f1c21a5b8..271d8c2a58 100644 --- a/core/chains/evm/logpoller/log_poller_internal_test.go +++ b/core/chains/evm/logpoller/log_poller_internal_test.go @@ -31,7 +31,7 @@ var ( ) // Validate that filters stored in log_filters_table match the filters stored in memory -func validateFiltersTable(t *testing.T, lp *logPoller, orm *ORM) { +func validateFiltersTable(t *testing.T, lp *logPoller, orm *DbORM) { filters, err := orm.LoadFilters() require.NoError(t, err) require.Equal(t, len(filters), len(lp.filters)) diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index c434d18c99..e21fc0f383 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -39,23 +39,17 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -func logRuntime(t *testing.T, start time.Time) { +func logRuntime(t testing.TB, start time.Time) { t.Log("runtime", time.Since(start)) } -func TestPopulateLoadedDB(t *testing.T) { - t.Skip("Only for local load testing and query analysis") - lggr := logger.TestLogger(t) - _, db := heavyweight.FullTestDBV2(t, "logs_scale", nil) - chainID := big.NewInt(137) - - o := logpoller.NewORM(big.NewInt(137), db, lggr, pgtest.NewQConfig(true)) +func populateDatabase(t testing.TB, o *logpoller.DbORM, chainID *big.Int) (common.Hash, common.Address, common.Address) { event1 := EmitterABI.Events["Log1"].ID address1 := common.HexToAddress("0x2ab9a2Dc53736b361b72d900CdF9F78F9406fbbb") address2 := common.HexToAddress("0x6E225058950f237371261C985Db6bDe26df2200E") + startDate := time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC) - // We start at 1 just so block number > 0 - for j := 1; j < 1000; j++ { + for j := 1; j < 100; j++ { var logs []logpoller.Log // Max we can insert per batch for i := 0; i < 1000; i++ { @@ -63,23 +57,60 @@ func TestPopulateLoadedDB(t *testing.T) { if (i+(1000*j))%2 == 0 { addr = address2 } + blockNumber := int64(i + (1000 * j)) + blockTimestamp := startDate.Add(time.Duration(j*1000) * time.Hour) + logs = append(logs, logpoller.Log{ - EvmChainId: utils.NewBig(chainID), - LogIndex: 1, - BlockHash: common.HexToHash(fmt.Sprintf("0x%d", i+(1000*j))), - BlockNumber: int64(i + (1000 * j)), - EventSig: event1, - Topics: [][]byte{event1[:], logpoller.EvmWord(uint64(i + 1000*j)).Bytes()}, - Address: addr, - TxHash: common.HexToHash("0x1234"), - Data: logpoller.EvmWord(uint64(i + 1000*j)).Bytes(), + EvmChainId: utils.NewBig(chainID), + LogIndex: 1, + BlockHash: common.HexToHash(fmt.Sprintf("0x%d", i+(1000*j))), + BlockNumber: blockNumber, + BlockTimestamp: blockTimestamp, + EventSig: event1, + Topics: [][]byte{event1[:], logpoller.EvmWord(uint64(i + 1000*j)).Bytes()}, + Address: addr, + TxHash: utils.RandomAddress().Hash(), + Data: logpoller.EvmWord(uint64(i + 1000*j)).Bytes(), + CreatedAt: blockTimestamp, }) + } require.NoError(t, o.InsertLogs(logs)) + require.NoError(t, o.InsertBlock(utils.RandomAddress().Hash(), int64((j+1)*1000-1), startDate.Add(time.Duration(j*1000)*time.Hour))) } + + return event1, address1, address2 +} + +func BenchmarkSelectLogsCreatedAfter(b *testing.B) { + chainId := big.NewInt(137) + _, db := heavyweight.FullTestDBV2(b, "logs_scale", nil) + o := logpoller.NewORM(chainId, db, logger.TestLogger(b), pgtest.NewQConfig(false)) + event, address, _ := populateDatabase(b, o, chainId) + + // Setting searchDate to pick around 5k logs + searchDate := time.Date(2020, 1, 1, 12, 12, 12, 0, time.UTC) + + b.ResetTimer() + + for i := 0; i < b.N; i++ { + logs, err := o.SelectLogsCreatedAfter(address, event, searchDate, 500) + require.NotZero(b, len(logs)) + require.NoError(b, err) + } +} + +func TestPopulateLoadedDB(t *testing.T) { + t.Skip("Only for local load testing and query analysis") + _, db := heavyweight.FullTestDBV2(t, "logs_scale", nil) + chainID := big.NewInt(137) + + o := logpoller.NewORM(big.NewInt(137), db, logger.TestLogger(t), pgtest.NewQConfig(true)) + event1, address1, address2 := populateDatabase(t, o, chainID) + func() { defer logRuntime(t, time.Now()) - _, err1 := o.SelectLogsByBlockRangeFilter(750000, 800000, address1, event1) + _, err1 := o.SelectLogs(750000, 800000, address1, event1) require.NoError(t, err1) }() func() { @@ -92,7 +123,7 @@ func TestPopulateLoadedDB(t *testing.T) { require.NoError(t, o.InsertBlock(common.HexToHash("0x10"), 1000000, time.Now())) func() { defer logRuntime(t, time.Now()) - lgs, err1 := o.SelectDataWordRange(address1, event1, 0, logpoller.EvmWord(500000), logpoller.EvmWord(500020), 0) + lgs, err1 := o.SelectLogsDataWordRange(address1, event1, 0, logpoller.EvmWord(500000), logpoller.EvmWord(500020), 0) require.NoError(t, err1) // 10 since every other log is for address1 assert.Equal(t, 10, len(lgs)) @@ -107,7 +138,7 @@ func TestPopulateLoadedDB(t *testing.T) { func() { defer logRuntime(t, time.Now()) - lgs, err1 := o.SelectIndexLogsTopicRange(address1, event1, 1, logpoller.EvmWord(500000), logpoller.EvmWord(500020), 0) + lgs, err1 := o.SelectIndexedLogsTopicRange(address1, event1, 1, logpoller.EvmWord(500000), logpoller.EvmWord(500020), 0) require.NoError(t, err1) assert.Equal(t, 10, len(lgs)) }() diff --git a/core/chains/evm/logpoller/observability.go b/core/chains/evm/logpoller/observability.go index 8dfa6e81d0..4e0ebe7418 100644 --- a/core/chains/evm/logpoller/observability.go +++ b/core/chains/evm/logpoller/observability.go @@ -1,11 +1,13 @@ package logpoller import ( + "math/big" "time" "github.com/ethereum/go-ethereum/common" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/smartcontractkit/sqlx" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -46,113 +48,199 @@ var ( }, []string{"evmChainID", "query"}) ) -// ObservedLogPoller is a decorator layer for LogPoller, responsible for pushing Prometheus metrics reporting duration and size of result set for some of the queries. -// It doesn't change internal logic, because all calls are delegated to the origin LogPoller -type ObservedLogPoller struct { - LogPoller +// ObservedORM is a decorator layer for ORM used by LogPoller, responsible for pushing Prometheus metrics reporting duration and size of result set for the queries. +// It doesn't change internal logic, because all calls are delegated to the origin ORM +type ObservedORM struct { + ORM queryDuration *prometheus.HistogramVec datasetSize *prometheus.GaugeVec chainId string } -// NewObservedLogPoller creates an observed version of log poller created by NewLogPoller +// NewObservedORM creates an observed version of log poller's ORM created by NewORM // Please see ObservedLogPoller for more details on how latencies are measured -func NewObservedLogPoller(orm *ORM, ec Client, lggr logger.Logger, pollPeriod time.Duration, - finalityDepth int64, backfillBatchSize int64, rpcBatchSize int64, keepBlocksDepth int64) LogPoller { - - return &ObservedLogPoller{ - LogPoller: NewLogPoller(orm, ec, lggr, pollPeriod, finalityDepth, backfillBatchSize, rpcBatchSize, keepBlocksDepth), +func NewObservedORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *ObservedORM { + return &ObservedORM{ + ORM: NewORM(chainID, db, lggr, cfg), queryDuration: lpQueryDuration, datasetSize: lpQueryDataSets, - chainId: orm.chainID.String(), + chainId: chainID.String(), } } -func (o *ObservedLogPoller) LogsCreatedAfter(eventSig common.Hash, address common.Address, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "LogsCreatedAfter", func() ([]Log, error) { - return o.LogPoller.LogsCreatedAfter(eventSig, address, after, confs, qopts...) +func (o *ObservedORM) Q() pg.Q { + return o.ORM.Q() +} + +func (o *ObservedORM) InsertLogs(logs []Log, qopts ...pg.QOpt) error { + return withObservedExec(o, "InsertLogs", func() error { + return o.ORM.InsertLogs(logs, qopts...) + }) +} + +func (o *ObservedORM) InsertBlock(h common.Hash, n int64, t time.Time, qopts ...pg.QOpt) error { + return withObservedExec(o, "InsertBlock", func() error { + return o.ORM.InsertBlock(h, n, t, qopts...) + }) +} + +func (o *ObservedORM) InsertFilter(filter Filter, qopts ...pg.QOpt) error { + return withObservedExec(o, "InsertFilter", func() error { + return o.ORM.InsertFilter(filter, qopts...) + }) +} + +func (o *ObservedORM) LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) { + return withObservedQuery(o, "LoadFilters", func() (map[string]Filter, error) { + return o.ORM.LoadFilters(qopts...) + }) +} + +func (o *ObservedORM) DeleteFilter(name string, qopts ...pg.QOpt) error { + return withObservedExec(o, "DeleteFilter", func() error { + return o.ORM.DeleteFilter(name, qopts...) + }) +} + +func (o *ObservedORM) DeleteBlocksAfter(start int64, qopts ...pg.QOpt) error { + return withObservedExec(o, "DeleteBlocksAfter", func() error { + return o.ORM.DeleteBlocksAfter(start, qopts...) + }) +} + +func (o *ObservedORM) DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error { + return withObservedExec(o, "DeleteBlocksBefore", func() error { + return o.ORM.DeleteBlocksBefore(end, qopts...) + }) +} + +func (o *ObservedORM) DeleteLogsAfter(start int64, qopts ...pg.QOpt) error { + return withObservedExec(o, "DeleteLogsAfter", func() error { + return o.ORM.DeleteLogsAfter(start, qopts...) + }) +} + +func (o *ObservedORM) DeleteExpiredLogs(qopts ...pg.QOpt) error { + return withObservedExec(o, "DeleteExpiredLogs", func() error { + return o.ORM.DeleteExpiredLogs(qopts...) + }) +} + +func (o *ObservedORM) SelectBlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, error) { + return withObservedQuery(o, "SelectBlockByNumber", func() (*LogPollerBlock, error) { + return o.ORM.SelectBlockByNumber(n, qopts...) + }) +} + +func (o *ObservedORM) SelectLatestBlock(qopts ...pg.QOpt) (*LogPollerBlock, error) { + return withObservedQuery(o, "SelectLatestBlock", func() (*LogPollerBlock, error) { + return o.ORM.SelectLatestBlock(qopts...) + }) +} + +func (o *ObservedORM) SelectLatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs int, qopts ...pg.QOpt) (*Log, error) { + return withObservedQuery(o, "SelectLatestLogByEventSigWithConfs", func() (*Log, error) { + return o.ORM.SelectLatestLogByEventSigWithConfs(eventSig, address, confs, qopts...) + }) +} + +func (o *ObservedORM) SelectLogsWithSigs(start, end int64, address common.Address, eventSigs []common.Hash, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectLogsWithSigs", func() ([]Log, error) { + return o.ORM.SelectLogsWithSigs(start, end, address, eventSigs, qopts...) }) } -func (o *ObservedLogPoller) LatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs int, qopts ...pg.QOpt) (*Log, error) { - return withObservedQuery(o, "LatestLogByEventSigWithConfs", func() (*Log, error) { - return o.LogPoller.LatestLogByEventSigWithConfs(eventSig, address, confs, qopts...) +func (o *ObservedORM) SelectLogsCreatedAfter(address common.Address, eventSig common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectLogsCreatedAfter", func() ([]Log, error) { + return o.ORM.SelectLogsCreatedAfter(address, eventSig, after, confs, qopts...) }) } -func (o *ObservedLogPoller) LatestLogEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "LatestLogEventSigsAddrsWithConfs", func() ([]Log, error) { - return o.LogPoller.LatestLogEventSigsAddrsWithConfs(fromBlock, eventSigs, addresses, confs, qopts...) +func (o *ObservedORM) SelectIndexedLogs(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectIndexedLogs", func() ([]Log, error) { + return o.ORM.SelectIndexedLogs(address, eventSig, topicIndex, topicValues, confs, qopts...) }) } -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(fromBlock, eventSigs, addresses, confs, qopts...) +func (o *ObservedORM) SelectIndexedLogsByBlockRange(start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectIndexedLogsByBlockRange", func() ([]Log, error) { + return o.ORM.SelectIndexedLogsByBlockRange(start, end, address, eventSig, topicIndex, topicValues, qopts...) }) } -func (o *ObservedLogPoller) IndexedLogs(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "IndexedLogs", func() ([]Log, error) { - return o.LogPoller.IndexedLogs(eventSig, address, topicIndex, topicValues, confs, qopts...) +func (o *ObservedORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectIndexedLogsCreatedAfter", func() ([]Log, error) { + return o.ORM.SelectIndexedLogsCreatedAfter(address, eventSig, topicIndex, topicValues, after, confs, qopts...) }) } -func (o *ObservedLogPoller) IndexedLogsByBlockRange(start, end int64, eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "IndexedLogsByBlockRange", func() ([]Log, error) { - return o.LogPoller.IndexedLogsByBlockRange(start, end, eventSig, address, topicIndex, topicValues, qopts...) +func (o *ObservedORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs int, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectIndexedLogsWithSigsExcluding", func() ([]Log, error) { + return o.ORM.SelectIndexedLogsWithSigsExcluding(sigA, sigB, topicIndex, address, startBlock, endBlock, confs, qopts...) }) } -func (o *ObservedLogPoller) IndexedLogsCreatedAfter(eventSig common.Hash, address common.Address, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "IndexedLogsCreatedAfter", func() ([]Log, error) { - return o.LogPoller.IndexedLogsCreatedAfter(eventSig, address, topicIndex, topicValues, after, confs, qopts...) +func (o *ObservedORM) SelectLogs(start, end int64, address common.Address, eventSig common.Hash, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectLogs", func() ([]Log, error) { + return o.ORM.SelectLogs(start, end, address, eventSig, qopts...) }) } -func (o *ObservedLogPoller) IndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (o *ObservedORM) IndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { return withObservedQueryAndResults(o, "IndexedLogsByTxHash", func() ([]Log, error) { - return o.LogPoller.IndexedLogsByTxHash(eventSig, txHash, qopts...) + return o.ORM.SelectIndexedLogsByTxHash(eventSig, txHash, qopts...) }) } -func (o *ObservedLogPoller) IndexedLogsTopicGreaterThan(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "IndexedLogsTopicGreaterThan", func() ([]Log, error) { - return o.LogPoller.IndexedLogsTopicGreaterThan(eventSig, address, topicIndex, topicValueMin, confs, qopts...) +func (o *ObservedORM) GetBlocksRange(start uint64, end uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) { + return withObservedQueryAndResults(o, "GetBlocksRange", func() ([]LogPollerBlock, error) { + return o.ORM.GetBlocksRange(start, end, qopts...) }) } -func (o *ObservedLogPoller) IndexedLogsTopicRange(eventSig common.Hash, address common.Address, topicIndex int, topicValueMin common.Hash, topicValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "IndexedLogsTopicRange", func() ([]Log, error) { - return o.LogPoller.IndexedLogsTopicRange(eventSig, address, topicIndex, topicValueMin, topicValueMax, confs, qopts...) +func (o *ObservedORM) SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectLatestLogEventSigsAddrsWithConfs", func() ([]Log, error) { + return o.ORM.SelectLatestLogEventSigsAddrsWithConfs(fromBlock, addresses, eventSigs, confs, qopts...) }) } -func (o *ObservedLogPoller) IndexedLogsWithSigsExcluding(address common.Address, eventSigA, eventSigB common.Hash, topicIndex int, fromBlock, toBlock int64, confs int, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "IndexedLogsWithSigsExcluding", func() ([]Log, error) { - return o.LogPoller.IndexedLogsWithSigsExcluding(address, eventSigA, eventSigB, topicIndex, fromBlock, toBlock, confs, qopts...) +func (o *ObservedORM) SelectLatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { + return withObservedQuery(o, "SelectLatestBlockByEventSigsAddrsWithConfs", func() (int64, error) { + return o.ORM.SelectLatestBlockByEventSigsAddrsWithConfs(fromBlock, eventSigs, addresses, confs, qopts...) }) } -func (o *ObservedLogPoller) LogsDataWordRange(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin, wordValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "LogsDataWordRange", func() ([]Log, error) { - return o.LogPoller.LogsDataWordRange(eventSig, address, wordIndex, wordValueMin, wordValueMax, confs, qopts...) +func (o *ObservedORM) SelectLogsDataWordRange(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectLogsDataWordRange", func() ([]Log, error) { + return o.ORM.SelectLogsDataWordRange(address, eventSig, wordIndex, wordValueMin, wordValueMax, confs, qopts...) }) } -func (o *ObservedLogPoller) LogsDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "LogsDataWordGreaterThan", func() ([]Log, error) { - return o.LogPoller.LogsDataWordGreaterThan(eventSig, address, wordIndex, wordValueMin, confs, qopts...) +func (o *ObservedORM) SelectLogsDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectLogsDataWordGreaterThan", func() ([]Log, error) { + return o.ORM.SelectLogsDataWordGreaterThan(address, eventSig, wordIndex, wordValueMin, confs, qopts...) }) } -func (o *ObservedLogPoller) LogsUntilBlockHashDataWordGreaterThan(eventSig common.Hash, address common.Address, wordIndex int, wordValueMin common.Hash, untilBlockHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { - return withObservedQueryAndResults(o, "LogsUntilBlockHashDataWordGreaterThan", func() ([]Log, error) { - return o.LogPoller.LogsUntilBlockHashDataWordGreaterThan(eventSig, address, wordIndex, wordValueMin, untilBlockHash, qopts...) +func (o *ObservedORM) SelectLogsUntilBlockHashDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, untilBlockHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectLogsUntilBlockHashDataWordGreaterThan", func() ([]Log, error) { + return o.ORM.SelectLogsUntilBlockHashDataWordGreaterThan(address, eventSig, wordIndex, wordValueMin, untilBlockHash, qopts...) }) } -func withObservedQueryAndResults[T any](o *ObservedLogPoller, queryName string, query func() ([]T, error)) ([]T, error) { +func (o *ObservedORM) SelectIndexedLogsTopicGreaterThan(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectIndexedLogsTopicGreaterThan", func() ([]Log, error) { + return o.ORM.SelectIndexedLogsTopicGreaterThan(address, eventSig, topicIndex, topicValueMin, confs, qopts...) + }) +} + +func (o *ObservedORM) SelectIndexedLogsTopicRange(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { + return withObservedQueryAndResults(o, "SelectIndexedLogsTopicRange", func() ([]Log, error) { + return o.ORM.SelectIndexedLogsTopicRange(address, eventSig, topicIndex, topicValueMin, topicValueMax, confs, qopts...) + }) +} + +func withObservedQueryAndResults[T any](o *ObservedORM, queryName string, query func() ([]T, error)) ([]T, error) { results, err := withObservedQuery(o, queryName, query) if err == nil { o.datasetSize. @@ -162,7 +250,7 @@ func withObservedQueryAndResults[T any](o *ObservedLogPoller, queryName string, return results, err } -func withObservedQuery[T any](o *ObservedLogPoller, queryName string, query func() (T, error)) (T, error) { +func withObservedQuery[T any](o *ObservedORM, queryName string, query func() (T, error)) (T, error) { queryStarted := time.Now() defer func() { o.queryDuration. @@ -171,3 +259,13 @@ func withObservedQuery[T any](o *ObservedLogPoller, queryName string, query func }() return query() } + +func withObservedExec(o *ObservedORM, query string, exec func() error) error { + queryStarted := time.Now() + defer func() { + o.queryDuration. + WithLabelValues(o.chainId, query). + Observe(float64(time.Since(queryStarted))) + }() + return exec() +} diff --git a/core/chains/evm/logpoller/observability_test.go b/core/chains/evm/logpoller/observability_test.go index 5bd0a772d9..c26b487bbd 100644 --- a/core/chains/evm/logpoller/observability_test.go +++ b/core/chains/evm/logpoller/observability_test.go @@ -25,20 +25,22 @@ func TestMultipleMetricsArePublished(t *testing.T) { lp := createObservedPollLogger(t, 100) require.Equal(t, 0, testutil.CollectAndCount(lp.queryDuration)) - _, _ = lp.IndexedLogs(common.Hash{}, common.Address{}, 1, []common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = lp.IndexedLogsByBlockRange(0, 1, common.Hash{}, common.Address{}, 1, []common.Hash{}, pg.WithParentCtx(ctx)) - _, _ = lp.IndexedLogsTopicGreaterThan(common.Hash{}, common.Address{}, 1, common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = lp.IndexedLogsTopicRange(common.Hash{}, common.Address{}, 1, common.Hash{}, common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = lp.IndexedLogsWithSigsExcluding(common.Address{}, common.Hash{}, common.Hash{}, 1, 0, 1, 1, pg.WithParentCtx(ctx)) - _, _ = lp.LogsDataWordRange(common.Hash{}, common.Address{}, 0, common.Hash{}, common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = lp.LogsDataWordGreaterThan(common.Hash{}, common.Address{}, 0, common.Hash{}, 1, pg.WithParentCtx(ctx)) - _, _ = lp.LogsCreatedAfter(common.Hash{}, common.Address{}, time.Now(), 0, pg.WithParentCtx(ctx)) - _, _ = lp.LatestLogByEventSigWithConfs(common.Hash{}, common.Address{}, 0, pg.WithParentCtx(ctx)) - _, _ = lp.LatestLogEventSigsAddrsWithConfs(0, []common.Hash{{}}, []common.Address{{}}, 1, pg.WithParentCtx(ctx)) - _, _ = lp.IndexedLogsCreatedAfter(common.Hash{}, common.Address{}, 0, []common.Hash{}, time.Now(), 0, pg.WithParentCtx(ctx)) - _, _ = lp.LogsUntilBlockHashDataWordGreaterThan(common.Hash{}, common.Address{}, 0, common.Hash{}, common.Hash{}, pg.WithParentCtx(ctx)) - - require.Equal(t, 12, testutil.CollectAndCount(lp.queryDuration)) + _, _ = lp.SelectIndexedLogs(common.Address{}, common.Hash{}, 1, []common.Hash{}, 1, pg.WithParentCtx(ctx)) + _, _ = lp.SelectIndexedLogsByBlockRange(0, 1, common.Address{}, common.Hash{}, 1, []common.Hash{}, pg.WithParentCtx(ctx)) + _, _ = lp.SelectIndexedLogsTopicGreaterThan(common.Address{}, common.Hash{}, 1, common.Hash{}, 1, pg.WithParentCtx(ctx)) + _, _ = lp.SelectIndexedLogsTopicRange(common.Address{}, common.Hash{}, 1, common.Hash{}, common.Hash{}, 1, pg.WithParentCtx(ctx)) + _, _ = lp.SelectIndexedLogsWithSigsExcluding(common.Hash{}, common.Hash{}, 1, common.Address{}, 0, 1, 1, pg.WithParentCtx(ctx)) + _, _ = lp.SelectLogsDataWordRange(common.Address{}, common.Hash{}, 0, common.Hash{}, common.Hash{}, 1, pg.WithParentCtx(ctx)) + _, _ = lp.SelectLogsDataWordGreaterThan(common.Address{}, common.Hash{}, 0, common.Hash{}, 1, pg.WithParentCtx(ctx)) + _, _ = lp.SelectLogsCreatedAfter(common.Address{}, common.Hash{}, time.Now(), 0, pg.WithParentCtx(ctx)) + _, _ = lp.SelectLatestLogByEventSigWithConfs(common.Hash{}, common.Address{}, 0, pg.WithParentCtx(ctx)) + _, _ = lp.SelectLatestLogEventSigsAddrsWithConfs(0, []common.Address{{}}, []common.Hash{{}}, 1, pg.WithParentCtx(ctx)) + _, _ = lp.SelectIndexedLogsCreatedAfter(common.Address{}, common.Hash{}, 0, []common.Hash{}, time.Now(), 0, pg.WithParentCtx(ctx)) + _, _ = lp.SelectLogsUntilBlockHashDataWordGreaterThan(common.Address{}, common.Hash{}, 0, common.Hash{}, common.Hash{}, pg.WithParentCtx(ctx)) + _ = lp.InsertLogs([]Log{}, pg.WithParentCtx(ctx)) + _ = lp.InsertBlock(common.Hash{}, 0, time.Now(), pg.WithParentCtx(ctx)) + + require.Equal(t, 14, testutil.CollectAndCount(lp.queryDuration)) require.Equal(t, 10, testutil.CollectAndCount(lp.datasetSize)) resetMetrics(*lp) } @@ -48,31 +50,15 @@ func TestShouldPublishDurationInCaseOfError(t *testing.T) { lp := createObservedPollLogger(t, 200) require.Equal(t, 0, testutil.CollectAndCount(lp.queryDuration)) - _, err := lp.LatestLogByEventSigWithConfs(common.Hash{}, common.Address{}, 0, pg.WithParentCtx(ctx)) + _, err := lp.SelectLatestLogByEventSigWithConfs(common.Hash{}, common.Address{}, 0, pg.WithParentCtx(ctx)) require.Error(t, err) require.Equal(t, 1, testutil.CollectAndCount(lp.queryDuration)) - require.Equal(t, 1, counterFromHistogramByLabels(t, lp.queryDuration, "200", "LatestLogByEventSigWithConfs")) + require.Equal(t, 1, counterFromHistogramByLabels(t, lp.queryDuration, "200", "SelectLatestLogByEventSigWithConfs")) resetMetrics(*lp) } -func TestNotObservedFunctions(t *testing.T) { - ctx := testutils.Context(t) - lp := createObservedPollLogger(t, 300) - require.Equal(t, 0, testutil.CollectAndCount(lp.queryDuration)) - - _, err := lp.Logs(0, 1, common.Hash{}, common.Address{}, pg.WithParentCtx(ctx)) - require.NoError(t, err) - - _, err = lp.LogsWithSigs(0, 1, []common.Hash{{}}, common.Address{}, pg.WithParentCtx(ctx)) - require.NoError(t, err) - - require.Equal(t, 0, testutil.CollectAndCount(lp.queryDuration)) - require.Equal(t, 0, testutil.CollectAndCount(lp.datasetSize)) - resetMetrics(*lp) -} - func TestMetricsAreProperlyPopulatedWithLabels(t *testing.T) { lp := createObservedPollLogger(t, 420) expectedCount := 9 @@ -105,16 +91,23 @@ func TestNotPublishingDatasetSizeInCaseOfError(t *testing.T) { require.Equal(t, 0, counterFromGaugeByLabels(lp.datasetSize, "420", "errorQuery")) } -func createObservedPollLogger(t *testing.T, chainId int64) *ObservedLogPoller { +func TestMetricsAreProperlyPopulatedForWrites(t *testing.T) { + lp := createObservedPollLogger(t, 420) + require.NoError(t, withObservedExec(lp, "execQuery", func() error { return nil })) + require.Error(t, withObservedExec(lp, "execQuery", func() error { return fmt.Errorf("error") })) + + require.Equal(t, 2, counterFromHistogramByLabels(t, lp.queryDuration, "420", "execQuery")) +} + +func createObservedPollLogger(t *testing.T, chainId int64) *ObservedORM { lggr, _ := logger.TestLoggerObserved(t, zapcore.ErrorLevel) db := pgtest.NewSqlxDB(t) - orm := NewORM(big.NewInt(chainId), db, lggr, pgtest.NewQConfig(true)) - return NewObservedLogPoller( - orm, nil, lggr, 1, 1, 1, 1, 1000, - ).(*ObservedLogPoller) + return NewObservedORM( + big.NewInt(chainId), db, lggr, pgtest.NewQConfig(true), + ) } -func resetMetrics(lp ObservedLogPoller) { +func resetMetrics(lp ObservedORM) { lp.queryDuration.Reset() lp.datasetSize.Reset() } diff --git a/core/chains/evm/logpoller/orm.go b/core/chains/evm/logpoller/orm.go index c062ef3e08..8cb80094c0 100644 --- a/core/chains/evm/logpoller/orm.go +++ b/core/chains/evm/logpoller/orm.go @@ -16,23 +16,67 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) -type ORM struct { +// ORM represents the persistent data access layer used by the log poller. At this moment, it's a bit leaky abstraction, because +// it exposes some of the database implementation details (e.g. pg.Q). Ideally it should be agnostic and could be applied to any persistence layer. +// What is more, LogPoller should not be aware of the underlying database implementation and delegate all the queries to the ORM. +type ORM interface { + Q() pg.Q + InsertLogs(logs []Log, qopts ...pg.QOpt) error + InsertBlock(h common.Hash, n int64, t time.Time, qopts ...pg.QOpt) error + InsertFilter(filter Filter, qopts ...pg.QOpt) error + + LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) + DeleteFilter(name string, qopts ...pg.QOpt) error + + DeleteBlocksAfter(start int64, qopts ...pg.QOpt) error + DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error + DeleteLogsAfter(start int64, qopts ...pg.QOpt) error + DeleteExpiredLogs(qopts ...pg.QOpt) error + + GetBlocksRange(start uint64, end uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) + SelectBlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, error) + SelectLatestBlock(qopts ...pg.QOpt) (*LogPollerBlock, error) + + SelectLogs(start, end int64, address common.Address, eventSig common.Hash, qopts ...pg.QOpt) ([]Log, error) + SelectLogsWithSigs(start, end int64, address common.Address, eventSigs []common.Hash, qopts ...pg.QOpt) ([]Log, error) + SelectLogsCreatedAfter(address common.Address, eventSig common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) + SelectLatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs int, qopts ...pg.QOpt) (*Log, error) + SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) + SelectLatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) + + SelectIndexedLogs(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) + SelectIndexedLogsByBlockRange(start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) + SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) + SelectIndexedLogsTopicGreaterThan(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) + SelectIndexedLogsTopicRange(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) + SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs int, qopts ...pg.QOpt) ([]Log, error) + SelectIndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) + SelectLogsDataWordRange(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) + SelectLogsDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) + SelectLogsUntilBlockHashDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, untilBlockHash common.Hash, qopts ...pg.QOpt) ([]Log, error) +} + +type DbORM struct { chainID *big.Int q pg.Q } -// NewORM creates an ORM scoped to chainID. -func NewORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *ORM { +// NewORM creates a DbORM scoped to chainID. +func NewORM(chainID *big.Int, db *sqlx.DB, lggr logger.Logger, cfg pg.QConfig) *DbORM { namedLogger := lggr.Named("Configs") q := pg.NewQ(db, namedLogger, cfg) - return &ORM{ + return &DbORM{ chainID: chainID, q: q, } } +func (o *DbORM) Q() pg.Q { + return o.q +} + // InsertBlock is idempotent to support replays. -func (o *ORM) InsertBlock(h common.Hash, n int64, t time.Time, qopts ...pg.QOpt) error { +func (o *DbORM) InsertBlock(h common.Hash, n int64, t time.Time, qopts ...pg.QOpt) error { q := o.q.WithOpts(qopts...) err := q.ExecQ(`INSERT INTO evm.log_poller_blocks (evm_chain_id, block_hash, block_number, block_timestamp, created_at) VALUES ($1, $2, $3, $4, NOW()) ON CONFLICT DO NOTHING`, utils.NewBig(o.chainID), h[:], n, t) @@ -43,7 +87,7 @@ func (o *ORM) InsertBlock(h common.Hash, n int64, t time.Time, qopts ...pg.QOpt) // // Each address/event pair must have a unique job id, so it may be removed when the job is deleted. // If a second job tries to overwrite the same pair, this should fail. -func (o *ORM) InsertFilter(filter Filter, qopts ...pg.QOpt) (err error) { +func (o *DbORM) InsertFilter(filter Filter, qopts ...pg.QOpt) (err error) { q := o.q.WithOpts(qopts...) addresses := make([][]byte, 0) events := make([][]byte, 0) @@ -65,13 +109,13 @@ func (o *ORM) InsertFilter(filter Filter, qopts ...pg.QOpt) (err error) { } // DeleteFilter removes all events,address pairs associated with the Filter -func (o *ORM) DeleteFilter(name string, qopts ...pg.QOpt) error { +func (o *DbORM) DeleteFilter(name string, qopts ...pg.QOpt) error { q := o.q.WithOpts(qopts...) return q.ExecQ(`DELETE FROM evm.log_poller_filters WHERE name = $1 AND evm_chain_id = $2`, name, utils.NewBig(o.chainID)) } // LoadFiltersForChain returns all filters for this chain -func (o *ORM) LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) { +func (o *DbORM) LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) { q := o.q.WithOpts(qopts...) rows := make([]Filter, 0) err := q.Select(&rows, `SELECT name, @@ -88,7 +132,7 @@ func (o *ORM) LoadFilters(qopts ...pg.QOpt) (map[string]Filter, error) { return filters, err } -func (o *ORM) SelectBlockByHash(h common.Hash, qopts ...pg.QOpt) (*LogPollerBlock, error) { +func (o *DbORM) SelectBlockByHash(h common.Hash, qopts ...pg.QOpt) (*LogPollerBlock, error) { q := o.q.WithOpts(qopts...) var b LogPollerBlock if err := q.Get(&b, `SELECT * FROM evm.log_poller_blocks WHERE block_hash = $1 AND evm_chain_id = $2`, h, utils.NewBig(o.chainID)); err != nil { @@ -97,7 +141,7 @@ func (o *ORM) SelectBlockByHash(h common.Hash, qopts ...pg.QOpt) (*LogPollerBloc return &b, nil } -func (o *ORM) SelectBlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, error) { +func (o *DbORM) SelectBlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, error) { q := o.q.WithOpts(qopts...) var b LogPollerBlock if err := q.Get(&b, `SELECT * FROM evm.log_poller_blocks WHERE block_number = $1 AND evm_chain_id = $2`, n, utils.NewBig(o.chainID)); err != nil { @@ -106,7 +150,7 @@ func (o *ORM) SelectBlockByNumber(n int64, qopts ...pg.QOpt) (*LogPollerBlock, e return &b, nil } -func (o *ORM) SelectLatestBlock(qopts ...pg.QOpt) (*LogPollerBlock, error) { +func (o *DbORM) SelectLatestBlock(qopts ...pg.QOpt) (*LogPollerBlock, error) { q := o.q.WithOpts(qopts...) var b LogPollerBlock if err := q.Get(&b, `SELECT * FROM evm.log_poller_blocks WHERE evm_chain_id = $1 ORDER BY block_number DESC LIMIT 1`, utils.NewBig(o.chainID)); err != nil { @@ -115,14 +159,14 @@ func (o *ORM) SelectLatestBlock(qopts ...pg.QOpt) (*LogPollerBlock, error) { return &b, nil } -func (o *ORM) SelectLatestLogEventSigWithConfs(eventSig common.Hash, address common.Address, confs int, qopts ...pg.QOpt) (*Log, error) { +func (o *DbORM) SelectLatestLogByEventSigWithConfs(eventSig common.Hash, address common.Address, confs int, qopts ...pg.QOpt) (*Log, error) { q := o.q.WithOpts(qopts...) var l Log if err := q.Get(&l, `SELECT * FROM evm.logs WHERE evm_chain_id = $1 AND event_sig = $2 AND address = $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) + 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) - $4 ORDER BY (block_number, log_index) DESC LIMIT 1`, utils.NewBig(o.chainID), eventSig, address, confs); err != nil { return nil, err } @@ -130,19 +174,19 @@ func (o *ORM) SelectLatestLogEventSigWithConfs(eventSig common.Hash, address com } // DeleteBlocksAfter delete all blocks after and including start. -func (o *ORM) DeleteBlocksAfter(start int64, qopts ...pg.QOpt) error { +func (o *DbORM) DeleteBlocksAfter(start int64, qopts ...pg.QOpt) error { q := o.q.WithOpts(qopts...) return q.ExecQ(`DELETE FROM evm.log_poller_blocks WHERE block_number >= $1 AND evm_chain_id = $2`, start, utils.NewBig(o.chainID)) } // DeleteBlocksBefore delete all blocks before and including end. -func (o *ORM) DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error { +func (o *DbORM) DeleteBlocksBefore(end int64, qopts ...pg.QOpt) error { q := o.q.WithOpts(qopts...) _, err := q.Exec(`DELETE FROM evm.log_poller_blocks WHERE block_number <= $1 AND evm_chain_id = $2`, end, utils.NewBig(o.chainID)) return err } -func (o *ORM) DeleteLogsAfter(start int64, qopts ...pg.QOpt) error { +func (o *DbORM) DeleteLogsAfter(start int64, qopts ...pg.QOpt) error { q := o.q.WithOpts(qopts...) return q.ExecQ(`DELETE FROM evm.logs WHERE block_number >= $1 AND evm_chain_id = $2`, start, utils.NewBig(o.chainID)) } @@ -155,7 +199,7 @@ type Exp struct { ShouldDelete bool } -func (o *ORM) DeleteExpiredLogs(qopts ...pg.QOpt) error { +func (o *DbORM) DeleteExpiredLogs(qopts ...pg.QOpt) error { qopts = append(qopts, pg.WithLongQueryTimeout()) q := o.q.WithOpts(qopts...) @@ -170,7 +214,7 @@ func (o *ORM) DeleteExpiredLogs(qopts ...pg.QOpt) error { } // InsertLogs is idempotent to support replays. -func (o *ORM) InsertLogs(logs []Log, qopts ...pg.QOpt) error { +func (o *DbORM) InsertLogs(logs []Log, qopts ...pg.QOpt) error { for _, log := range logs { if o.chainID.Cmp(log.EvmChainId.ToInt()) != 0 { return errors.Errorf("invalid chainID in log got %v want %v", log.EvmChainId.ToInt(), o.chainID) @@ -203,7 +247,7 @@ func (o *ORM) InsertLogs(logs []Log, qopts ...pg.QOpt) error { return nil } -func (o *ORM) SelectLogsByBlockRange(start, end int64) ([]Log, error) { +func (o *DbORM) SelectLogsByBlockRange(start, end int64) ([]Log, error) { var logs []Log err := o.q.Select(&logs, ` SELECT * FROM evm.logs @@ -216,7 +260,7 @@ func (o *ORM) SelectLogsByBlockRange(start, end int64) ([]Log, error) { } // SelectLogsByBlockRangeFilter finds the logs in a given block range. -func (o *ORM) SelectLogsByBlockRangeFilter(start, end int64, address common.Address, eventSig common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectLogs(start, end int64, address common.Address, eventSig common.Hash, qopts ...pg.QOpt) ([]Log, error) { var logs []Log q := o.q.WithOpts(qopts...) err := q.Select(&logs, ` @@ -231,17 +275,22 @@ func (o *ORM) SelectLogsByBlockRangeFilter(start, end int64, address common.Addr } // SelectLogsCreatedAfter finds logs created after some timestamp. -func (o *ORM) SelectLogsCreatedAfter(eventSig []byte, address common.Address, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectLogsCreatedAfter(address common.Address, eventSig common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { + minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...) + if err != nil { + return nil, err + } + var logs []Log q := o.q.WithOpts(qopts...) - err := q.Select(&logs, ` + err = q.Select(&logs, ` SELECT * FROM evm.logs WHERE evm_chain_id = $1 AND address = $2 AND event_sig = $3 - AND created_at > $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) - ORDER BY created_at ASC`, utils.NewBig(o.chainID), address, eventSig, after, confs) + AND block_number > $4 + AND block_number <= $5 + ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig, minBlock, maxBlock) if err != nil { return nil, err } @@ -250,7 +299,7 @@ func (o *ORM) SelectLogsCreatedAfter(eventSig []byte, address common.Address, af // SelectLogsWithSigsByBlockRangeFilter finds the logs in the given block range with the given event signatures // emitted from the given address. -func (o *ORM) SelectLogsWithSigsByBlockRangeFilter(start, end int64, address common.Address, eventSigs []common.Hash, qopts ...pg.QOpt) (logs []Log, err error) { +func (o *DbORM) SelectLogsWithSigs(start, end int64, address common.Address, eventSigs []common.Hash, qopts ...pg.QOpt) (logs []Log, err error) { q := o.q.WithOpts(qopts...) sigs := make([][]byte, 0, len(eventSigs)) for _, sig := range eventSigs { @@ -288,7 +337,7 @@ ORDER BY (evm.logs.block_number, evm.logs.log_index)`, a) return logs, err } -func (o *ORM) GetBlocksRange(start uint64, end uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) { +func (o *DbORM) GetBlocksRange(start uint64, end uint64, qopts ...pg.QOpt) ([]LogPollerBlock, error) { var blocks []LogPollerBlock q := o.q.WithOpts(qopts...) err := q.Select(&blocks, ` @@ -302,7 +351,7 @@ func (o *ORM) GetBlocksRange(start uint64, end uint64, qopts ...pg.QOpt) ([]LogP } // SelectLatestLogEventSigsAddrsWithConfs finds the latest log by (address, event) combination that matches a list of Addresses and list of events -func (o *ORM) SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectLatestLogEventSigsAddrsWithConfs(fromBlock int64, addresses []common.Address, eventSigs []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { var logs []Log sigs := concatBytes(eventSigs) addrs := concatBytes(addresses) @@ -327,7 +376,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(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { +func (o *DbORM) SelectLatestBlockByEventSigsAddrsWithConfs(fromBlock int64, eventSigs []common.Hash, addresses []common.Address, confs int, qopts ...pg.QOpt) (int64, error) { var blockNumber int64 sigs := concatBytes(eventSigs) addrs := concatBytes(addresses) @@ -347,7 +396,7 @@ func (o *ORM) SelectLatestBlockNumberEventSigsAddrsWithConfs(fromBlock int64, ev return blockNumber, nil } -func (o *ORM) SelectDataWordRange(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectLogsDataWordRange(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin, wordValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { var logs []Log q := o.q.WithOpts(qopts...) err := q.Select(&logs, @@ -364,7 +413,7 @@ func (o *ORM) SelectDataWordRange(address common.Address, eventSig common.Hash, return logs, nil } -func (o *ORM) SelectDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectLogsDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { var logs []Log q := o.q.WithOpts(qopts...) err := q.Select(&logs, @@ -380,7 +429,7 @@ func (o *ORM) SelectDataWordGreaterThan(address common.Address, eventSig common. return logs, nil } -func (o *ORM) SelectIndexLogsTopicGreaterThan(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectIndexedLogsTopicGreaterThan(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { if err := validateTopicIndex(topicIndex); err != nil { return nil, err } @@ -400,7 +449,7 @@ func (o *ORM) SelectIndexLogsTopicGreaterThan(address common.Address, eventSig c return logs, nil } -func (o *ORM) SelectUntilBlockHashDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, untilBlockHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectLogsUntilBlockHashDataWordGreaterThan(address common.Address, eventSig common.Hash, wordIndex int, wordValueMin common.Hash, untilBlockHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { var logs []Log q := o.q.WithOpts(qopts...) err := q.Transaction(func(tx pg.Queryer) error { @@ -425,7 +474,7 @@ func (o *ORM) SelectUntilBlockHashDataWordGreaterThan(address common.Address, ev return logs, nil } -func (o *ORM) SelectIndexLogsTopicRange(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectIndexedLogsTopicRange(address common.Address, eventSig common.Hash, topicIndex int, topicValueMin, topicValueMax common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { if err := validateTopicIndex(topicIndex); err != nil { return nil, err } @@ -446,7 +495,7 @@ func (o *ORM) SelectIndexLogsTopicRange(address common.Address, eventSig common. return logs, nil } -func (o *ORM) SelectIndexedLogs(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectIndexedLogs(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, confs int, qopts ...pg.QOpt) ([]Log, error) { if err := validateTopicIndex(topicIndex); err != nil { return nil, err } @@ -469,7 +518,7 @@ func (o *ORM) SelectIndexedLogs(address common.Address, eventSig common.Hash, to } // SelectIndexedLogsByBlockRangeFilter finds the indexed logs in a given block range. -func (o *ORM) SelectIndexedLogsByBlockRangeFilter(start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectIndexedLogsByBlockRange(start, end int64, address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, qopts ...pg.QOpt) ([]Log, error) { if err := validateTopicIndex(topicIndex); err != nil { return nil, err } @@ -497,26 +546,31 @@ func validateTopicIndex(index int) error { return nil } -func (o *ORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { - q := o.q.WithOpts(qopts...) +func (o *DbORM) SelectIndexedLogsCreatedAfter(address common.Address, eventSig common.Hash, topicIndex int, topicValues []common.Hash, after time.Time, confs int, qopts ...pg.QOpt) ([]Log, error) { + minBlock, maxBlock, err := o.blocksRangeAfterTimestamp(after, confs, qopts...) + if err != nil { + return nil, err + } var logs []Log + q := o.q.WithOpts(qopts...) topicValuesBytes := concatBytes(topicValues) // Add 1 since postgresql arrays are 1-indexed. - err := q.Select(&logs, ` + err = q.Select(&logs, ` SELECT * FROM evm.logs WHERE evm.logs.evm_chain_id = $1 - AND address = $2 AND event_sig = $3 + AND address = $2 + AND event_sig = $3 AND topics[$4] = ANY($5) - AND created_at > $6 - 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) + AND block_number > $6 + AND block_number <= $7 + ORDER BY (block_number, log_index)`, utils.NewBig(o.chainID), address, eventSig.Bytes(), topicIndex+1, topicValuesBytes, minBlock, maxBlock) if err != nil { return nil, err } return logs, nil } -func (o *ORM) SelectIndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectIndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash, qopts ...pg.QOpt) ([]Log, error) { q := o.q.WithOpts(qopts...) var logs []Log err := q.Select(&logs, ` @@ -533,7 +587,7 @@ func (o *ORM) SelectIndexedLogsByTxHash(eventSig common.Hash, txHash common.Hash } // SelectIndexedLogsWithSigsExcluding query's for logs that have signature A and exclude logs that have a corresponding signature B, matching is done based on the topic index both logs should be inside the block range and have the minimum number of confirmations -func (o *ORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs int, qopts ...pg.QOpt) ([]Log, error) { +func (o *DbORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIndex int, address common.Address, startBlock, endBlock int64, confs int, qopts ...pg.QOpt) ([]Log, error) { if err := validateTopicIndex(topicIndex); err != nil { return nil, err } @@ -569,7 +623,27 @@ func (o *ORM) SelectIndexedLogsWithSigsExcluding(sigA, sigB common.Hash, topicIn return nil, err } return logs, nil +} +func (o *DbORM) blocksRangeAfterTimestamp(after time.Time, confs int, qopts ...pg.QOpt) (int64, int64, error) { + type blockRange struct { + MinBlockNumber int64 `db:"min_block"` + MaxBlockNumber int64 `db:"max_block"` + } + + var br blockRange + q := o.q.WithOpts(qopts...) + err := q.Get(&br, ` + SELECT + coalesce(min(block_number), 0) as min_block, + coalesce(max(block_number), 0) as max_block + FROM evm.log_poller_blocks + WHERE evm_chain_id = $1 + AND block_timestamp > $2`, utils.NewBig(o.chainID), after) + if err != nil { + return 0, 0, err + } + return br.MinBlockNumber, br.MaxBlockNumber - int64(confs), nil } type bytesProducer interface { diff --git a/core/chains/evm/logpoller/orm_test.go b/core/chains/evm/logpoller/orm_test.go index 28f3e8da8e..531aec2ff3 100644 --- a/core/chains/evm/logpoller/orm_test.go +++ b/core/chains/evm/logpoller/orm_test.go @@ -293,36 +293,36 @@ func TestORM(t *testing.T) { require.Equal(t, 1, len(logs)) assert.Equal(t, []byte("hello"), logs[0].Data) - logs, err = o1.SelectLogsByBlockRangeFilter(1, 1, common.HexToAddress("0x1234"), topic) + logs, err = o1.SelectLogs(1, 1, common.HexToAddress("0x1234"), topic) require.NoError(t, err) assert.Equal(t, 0, len(logs)) - logs, err = o1.SelectLogsByBlockRangeFilter(10, 10, common.HexToAddress("0x1234"), topic) + logs, err = o1.SelectLogs(10, 10, common.HexToAddress("0x1234"), topic) require.NoError(t, err) require.Equal(t, 1, len(logs)) // With no blocks, should be an error - _, err = o1.SelectLatestLogEventSigWithConfs(topic, common.HexToAddress("0x1234"), 0) + _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 0) require.Error(t, err) assert.True(t, errors.Is(err, sql.ErrNoRows)) // With block 10, only 0 confs should work require.NoError(t, o1.InsertBlock(common.HexToHash("0x1234"), 10, time.Now())) - log, err := o1.SelectLatestLogEventSigWithConfs(topic, common.HexToAddress("0x1234"), 0) + log, err := o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 0) require.NoError(t, err) assert.Equal(t, int64(10), log.BlockNumber) - _, err = o1.SelectLatestLogEventSigWithConfs(topic, common.HexToAddress("0x1234"), 1) + _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 1) require.Error(t, err) assert.True(t, errors.Is(err, sql.ErrNoRows)) // With block 12, anything <=2 should work require.NoError(t, o1.DeleteBlocksAfter(10)) require.NoError(t, o1.InsertBlock(common.HexToHash("0x1234"), 11, time.Now())) require.NoError(t, o1.InsertBlock(common.HexToHash("0x1235"), 12, time.Now())) - _, err = o1.SelectLatestLogEventSigWithConfs(topic, common.HexToAddress("0x1234"), 0) + _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 0) require.NoError(t, err) - _, err = o1.SelectLatestLogEventSigWithConfs(topic, common.HexToAddress("0x1234"), 1) + _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 1) require.NoError(t, err) - _, err = o1.SelectLatestLogEventSigWithConfs(topic, common.HexToAddress("0x1234"), 2) + _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 2) require.NoError(t, err) - _, err = o1.SelectLatestLogEventSigWithConfs(topic, common.HexToAddress("0x1234"), 3) + _, err = o1.SelectLatestLogByEventSigWithConfs(topic, common.HexToAddress("0x1234"), 3) require.Error(t, err) assert.True(t, errors.Is(err, sql.ErrNoRows)) @@ -423,7 +423,7 @@ func TestORM(t *testing.T) { require.Zero(t, len(logs)) } -func insertLogsTopicValueRange(t *testing.T, chainID *big.Int, o *logpoller.ORM, addr common.Address, blockNumber int, eventSig common.Hash, start, stop int) { +func insertLogsTopicValueRange(t *testing.T, chainID *big.Int, o *logpoller.DbORM, addr common.Address, blockNumber int, eventSig common.Hash, start, stop int) { var lgs []logpoller.Log for i := start; i <= stop; i++ { lgs = append(lgs, logpoller.Log{ @@ -459,45 +459,45 @@ func TestORM_IndexedLogs(t *testing.T) { require.NoError(t, err) assert.Equal(t, 2, len(lgs)) - lgs, err = o1.SelectIndexedLogsByBlockRangeFilter(1, 1, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}) + lgs, err = o1.SelectIndexedLogsByBlockRange(1, 1, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) - lgs, err = o1.SelectIndexedLogsByBlockRangeFilter(1, 2, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(2)}) + lgs, err = o1.SelectIndexedLogsByBlockRange(1, 2, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(2)}) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) - lgs, err = o1.SelectIndexedLogsByBlockRangeFilter(1, 2, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}) + lgs, err = o1.SelectIndexedLogsByBlockRange(1, 2, addr, eventSig, 1, []common.Hash{logpoller.EvmWord(1)}) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) - _, err = o1.SelectIndexedLogsByBlockRangeFilter(1, 2, addr, eventSig, 0, []common.Hash{logpoller.EvmWord(1)}) + _, err = o1.SelectIndexedLogsByBlockRange(1, 2, addr, eventSig, 0, []common.Hash{logpoller.EvmWord(1)}) require.Error(t, err) assert.Contains(t, err.Error(), "invalid index for topic: 0") - _, err = o1.SelectIndexedLogsByBlockRangeFilter(1, 2, addr, eventSig, 4, []common.Hash{logpoller.EvmWord(1)}) + _, err = o1.SelectIndexedLogsByBlockRange(1, 2, addr, eventSig, 4, []common.Hash{logpoller.EvmWord(1)}) require.Error(t, err) assert.Contains(t, err.Error(), "invalid index for topic: 4") - lgs, err = o1.SelectIndexLogsTopicGreaterThan(addr, eventSig, 1, logpoller.EvmWord(2), 0) + lgs, err = o1.SelectIndexedLogsTopicGreaterThan(addr, eventSig, 1, logpoller.EvmWord(2), 0) require.NoError(t, err) assert.Equal(t, 2, len(lgs)) - lgs, err = o1.SelectIndexLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) + lgs, err = o1.SelectIndexedLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) assert.Equal(t, logpoller.EvmWord(3).Bytes(), lgs[0].GetTopics()[1].Bytes()) - lgs, err = o1.SelectIndexLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(1), logpoller.EvmWord(3), 0) + lgs, err = o1.SelectIndexedLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(1), logpoller.EvmWord(3), 0) require.NoError(t, err) assert.Equal(t, 3, len(lgs)) // Check confirmations work as expected. require.NoError(t, o1.InsertBlock(common.HexToHash("0x2"), 2, time.Now())) - lgs, err = o1.SelectIndexLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(4), logpoller.EvmWord(4), 1) + lgs, err = o1.SelectIndexedLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(4), logpoller.EvmWord(4), 1) require.NoError(t, err) assert.Equal(t, 0, len(lgs)) require.NoError(t, o1.InsertBlock(common.HexToHash("0x3"), 3, time.Now())) - lgs, err = o1.SelectIndexLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(4), logpoller.EvmWord(4), 1) + lgs, err = o1.SelectIndexedLogsTopicRange(addr, eventSig, 1, logpoller.EvmWord(4), logpoller.EvmWord(4), 1) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) } @@ -600,48 +600,48 @@ func TestORM_DataWords(t *testing.T) { }, })) // Outside range should fail. - lgs, err := o1.SelectDataWordRange(addr, eventSig, 0, logpoller.EvmWord(2), logpoller.EvmWord(2), 0) + lgs, err := o1.SelectLogsDataWordRange(addr, eventSig, 0, logpoller.EvmWord(2), logpoller.EvmWord(2), 0) require.NoError(t, err) assert.Equal(t, 0, len(lgs)) // Range including log should succeed - lgs, err = o1.SelectDataWordRange(addr, eventSig, 0, logpoller.EvmWord(1), logpoller.EvmWord(2), 0) + lgs, err = o1.SelectLogsDataWordRange(addr, eventSig, 0, logpoller.EvmWord(1), logpoller.EvmWord(2), 0) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) // Range only covering log should succeed - lgs, err = o1.SelectDataWordRange(addr, eventSig, 0, logpoller.EvmWord(1), logpoller.EvmWord(1), 0) + lgs, err = o1.SelectLogsDataWordRange(addr, eventSig, 0, logpoller.EvmWord(1), logpoller.EvmWord(1), 0) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) // Cannot query for unconfirmed second log. - lgs, err = o1.SelectDataWordRange(addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) + lgs, err = o1.SelectLogsDataWordRange(addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) require.NoError(t, err) assert.Equal(t, 0, len(lgs)) // Confirm it, then can query. require.NoError(t, o1.InsertBlock(common.HexToHash("0x2"), 2, time.Now())) - lgs, err = o1.SelectDataWordRange(addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) + lgs, err = o1.SelectLogsDataWordRange(addr, eventSig, 1, logpoller.EvmWord(3), logpoller.EvmWord(3), 0) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) assert.Equal(t, lgs[0].Data, append(logpoller.EvmWord(2).Bytes(), logpoller.EvmWord(3).Bytes()...)) // Check greater than 1 yields both logs. - lgs, err = o1.SelectDataWordGreaterThan(addr, eventSig, 0, logpoller.EvmWord(1), 0) + lgs, err = o1.SelectLogsDataWordGreaterThan(addr, eventSig, 0, logpoller.EvmWord(1), 0) require.NoError(t, err) assert.Equal(t, 2, len(lgs)) // Unknown hash should an error - lgs, err = o1.SelectUntilBlockHashDataWordGreaterThan(addr, eventSig, 0, logpoller.EvmWord(1), common.HexToHash("0x3")) + lgs, err = o1.SelectLogsUntilBlockHashDataWordGreaterThan(addr, eventSig, 0, logpoller.EvmWord(1), common.HexToHash("0x3")) require.Error(t, err) assert.Equal(t, 0, len(lgs)) // 1 block should include first log - lgs, err = o1.SelectUntilBlockHashDataWordGreaterThan(addr, eventSig, 0, logpoller.EvmWord(1), common.HexToHash("0x1")) + lgs, err = o1.SelectLogsUntilBlockHashDataWordGreaterThan(addr, eventSig, 0, logpoller.EvmWord(1), common.HexToHash("0x1")) require.NoError(t, err) assert.Equal(t, 1, len(lgs)) // 2 block should include both - lgs, err = o1.SelectUntilBlockHashDataWordGreaterThan(addr, eventSig, 0, logpoller.EvmWord(1), common.HexToHash("0x2")) + lgs, err = o1.SelectLogsUntilBlockHashDataWordGreaterThan(addr, eventSig, 0, logpoller.EvmWord(1), common.HexToHash("0x2")) require.NoError(t, err) assert.Equal(t, 2, len(lgs)) } @@ -651,7 +651,7 @@ func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) { o1 := th.ORM // Insert logs on different topics, should be able to read them - // back using SelectLogsWithSigsByBlockRangeFilter and specifying + // back using SelectLogsWithSigs and specifying // said topics. topic := common.HexToHash("0x1599") topic2 := common.HexToHash("0x1600") @@ -727,7 +727,7 @@ func TestORM_SelectLogsWithSigsByBlockRangeFilter(t *testing.T) { require.NoError(t, o1.InsertLogs(inputLogs)) startBlock, endBlock := int64(10), int64(15) - logs, err := o1.SelectLogsWithSigsByBlockRangeFilter(startBlock, endBlock, sourceAddr, []common.Hash{ + logs, err := o1.SelectLogsWithSigs(startBlock, endBlock, sourceAddr, []common.Hash{ topic, topic2, }) @@ -792,7 +792,7 @@ func TestLogPoller_Logs(t *testing.T) { assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000005", lgs[5].BlockHash.String()) // Filter by Address and topic - lgs, err = th.ORM.SelectLogsByBlockRangeFilter(1, 3, address1, event1) + lgs, err = th.ORM.SelectLogs(1, 3, address1, event1) require.NoError(t, err) require.Equal(t, 2, len(lgs)) assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000003", lgs[0].BlockHash.String()) @@ -802,7 +802,7 @@ func TestLogPoller_Logs(t *testing.T) { assert.Equal(t, address1, lgs[1].Address) // Filter by block - lgs, err = th.ORM.SelectLogsByBlockRangeFilter(2, 2, address2, event1) + lgs, err = th.ORM.SelectLogs(2, 2, address2, event1) require.NoError(t, err) require.Equal(t, 1, len(lgs)) assert.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000004", lgs[0].BlockHash.String()) @@ -832,7 +832,7 @@ func BenchmarkLogs(b *testing.B) { require.NoError(b, o.InsertLogs(lgs)) b.ResetTimer() for n := 0; n < b.N; n++ { - _, err := o.SelectDataWordRange(addr, EmitterABI.Events["Log1"].ID, 0, logpoller.EvmWord(8000), logpoller.EvmWord(8002), 0) + _, err := o.SelectLogsDataWordRange(addr, EmitterABI.Events["Log1"].ID, 0, logpoller.EvmWord(8000), logpoller.EvmWord(8002), 0) require.NoError(b, err) } } @@ -1087,16 +1087,16 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { th := SetupTH(t, 2, 3, 2) event1 := EmitterABI.Events["Log1"].ID event2 := EmitterABI.Events["Log2"].ID - address1 := common.HexToAddress("0xA") - address2 := common.HexToAddress("0xB") + address1 := utils.RandomAddress() + address2 := utils.RandomAddress() require.NoError(t, th.ORM.InsertLogs([]logpoller.Log{ - GenLog(th.ChainID, 1, 1, "0x1", event1[:], address1), - GenLog(th.ChainID, 2, 1, "0x2", event2[:], address2), - GenLog(th.ChainID, 2, 2, "0x4", event2[:], address2), - GenLog(th.ChainID, 2, 3, "0x6", event2[:], address2), + GenLog(th.ChainID, 1, 1, utils.RandomAddress().String(), event1[:], address1), + GenLog(th.ChainID, 2, 1, utils.RandomAddress().String(), event2[:], address2), + GenLog(th.ChainID, 2, 2, utils.RandomAddress().String(), event2[:], address2), + GenLog(th.ChainID, 2, 3, utils.RandomAddress().String(), event2[:], address2), })) - require.NoError(t, th.ORM.InsertBlock(common.HexToHash("0x1"), 3, time.Now())) + require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 3, time.Now())) tests := []struct { name string @@ -1165,9 +1165,104 @@ func TestSelectLatestBlockNumberEventSigsAddrsWithConfs(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - blockNumber, err := th.ORM.SelectLatestBlockNumberEventSigsAddrsWithConfs(tt.fromBlock, tt.events, tt.addrs, tt.confs) + blockNumber, err := th.ORM.SelectLatestBlockByEventSigsAddrsWithConfs(tt.fromBlock, tt.events, tt.addrs, tt.confs) require.NoError(t, err) assert.Equal(t, tt.expectedBlockNumber, blockNumber) }) } } + +func TestSelectLogsCreatedAfter(t *testing.T) { + th := SetupTH(t, 2, 3, 2) + event := EmitterABI.Events["Log1"].ID + address := utils.RandomAddress() + + past := time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC) + now := time.Date(2020, 1, 1, 12, 12, 12, 0, time.UTC) + future := time.Date(2030, 1, 1, 12, 12, 12, 0, time.UTC) + + require.NoError(t, th.ORM.InsertLogs([]logpoller.Log{ + GenLog(th.ChainID, 1, 1, utils.RandomAddress().String(), event[:], address), + GenLog(th.ChainID, 1, 2, utils.RandomAddress().String(), event[:], address), + GenLog(th.ChainID, 2, 2, utils.RandomAddress().String(), event[:], address), + GenLog(th.ChainID, 1, 3, utils.RandomAddress().String(), event[:], address), + })) + require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 1, past)) + require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 2, now)) + require.NoError(t, th.ORM.InsertBlock(utils.RandomAddress().Hash(), 3, future)) + + type expectedLog struct { + block int64 + log int64 + } + + tests := []struct { + name string + confs int + after time.Time + expectedLogs []expectedLog + }{ + { + name: "picks logs after block 1", + confs: 0, + after: past.Add(-time.Hour), + expectedLogs: []expectedLog{ + {block: 2, log: 1}, + {block: 2, log: 2}, + {block: 3, log: 1}, + }, + }, + { + name: "skips blocks with not enough confirmations", + confs: 1, + after: past.Add(-time.Hour), + expectedLogs: []expectedLog{ + {block: 2, log: 1}, + {block: 2, log: 2}, + }, + }, + { + name: "limits number of blocks by block_timestamp", + confs: 0, + after: now.Add(-time.Hour), + expectedLogs: []expectedLog{ + {block: 3, log: 1}, + }, + }, + { + name: "returns empty dataset for future timestamp", + confs: 0, + after: future, + expectedLogs: []expectedLog{}, + }, + { + name: "returns empty dataset when too many confirmations are required", + confs: 3, + after: past.Add(-time.Hour), + expectedLogs: []expectedLog{}, + }, + } + for _, tt := range tests { + t.Run("SelectLogsCreatedAfter"+tt.name, func(t *testing.T) { + logs, err := th.ORM.SelectLogsCreatedAfter(address, event, tt.after, tt.confs) + require.NoError(t, err) + assert.Len(t, logs, len(tt.expectedLogs)) + + for i, log := range logs { + assert.Equal(t, tt.expectedLogs[i].block, log.BlockNumber) + assert.Equal(t, tt.expectedLogs[i].log, log.LogIndex) + } + }) + + t.Run("SelectIndexedLogsCreatedAfter"+tt.name, func(t *testing.T) { + logs, err := th.ORM.SelectIndexedLogsCreatedAfter(address, event, 0, []common.Hash{event}, tt.after, tt.confs) + require.NoError(t, err) + assert.Len(t, logs, len(tt.expectedLogs)) + + for i, log := range logs { + assert.Equal(t, tt.expectedLogs[i].block, log.BlockNumber) + assert.Equal(t, tt.expectedLogs[i].log, log.LogIndex) + } + }) + } +} diff --git a/core/chains/evm/monitor/balance.go b/core/chains/evm/monitor/balance.go index 8dbd4ed850..28682f2509 100644 --- a/core/chains/evm/monitor/balance.go +++ b/core/chains/evm/monitor/balance.go @@ -47,8 +47,10 @@ type ( NullBalanceMonitor struct{} ) +var _ BalanceMonitor = (*balanceMonitor)(nil) + // NewBalanceMonitor returns a new balanceMonitor -func NewBalanceMonitor(ethClient evmclient.Client, ethKeyStore keystore.Eth, logger logger.Logger) BalanceMonitor { +func NewBalanceMonitor(ethClient evmclient.Client, ethKeyStore keystore.Eth, logger logger.Logger) *balanceMonitor { chainId := ethClient.ConfiguredChainID() bm := &balanceMonitor{ utils.StartStopOnce{}, diff --git a/core/chains/evm/monitor/balance_helpers_test.go b/core/chains/evm/monitor/balance_helpers_test.go new file mode 100644 index 0000000000..624aa69f06 --- /dev/null +++ b/core/chains/evm/monitor/balance_helpers_test.go @@ -0,0 +1,7 @@ +package monitor + +func (bm *balanceMonitor) WorkDone() <-chan struct{} { + return bm.sleeperTask.(interface { + WorkDone() <-chan struct{} + }).WorkDone() +} diff --git a/core/chains/evm/monitor/balance_test.go b/core/chains/evm/monitor/balance_test.go index c908c39567..d641738181 100644 --- a/core/chains/evm/monitor/balance_test.go +++ b/core/chains/evm/monitor/balance_test.go @@ -169,12 +169,9 @@ func TestBalanceMonitor_OnNewLongestChain_UpdatesBalance(t *testing.T) { // Do the thing bm.OnNewLongestChain(testutils.Context(t), head) - gomega.NewWithT(t).Eventually(func() *big.Int { - return bm.GetEthBalance(k0Addr).ToInt() - }).Should(gomega.Equal(k0bal)) - gomega.NewWithT(t).Eventually(func() *big.Int { - return bm.GetEthBalance(k1Addr).ToInt() - }).Should(gomega.Equal(k1bal)) + <-bm.WorkDone() + assert.Equal(t, k0bal, bm.GetEthBalance(k0Addr).ToInt()) + assert.Equal(t, k1bal, bm.GetEthBalance(k1Addr).ToInt()) // Do it again k0bal2 := big.NewInt(142) @@ -187,12 +184,9 @@ func TestBalanceMonitor_OnNewLongestChain_UpdatesBalance(t *testing.T) { bm.OnNewLongestChain(testutils.Context(t), head) - gomega.NewWithT(t).Eventually(func() *big.Int { - return bm.GetEthBalance(k0Addr).ToInt() - }).Should(gomega.Equal(k0bal2)) - gomega.NewWithT(t).Eventually(func() *big.Int { - return bm.GetEthBalance(k1Addr).ToInt() - }).Should(gomega.Equal(k1bal2)) + <-bm.WorkDone() + assert.Equal(t, k0bal2, bm.GetEthBalance(k0Addr).ToInt()) + assert.Equal(t, k1bal2, bm.GetEthBalance(k1Addr).ToInt()) }) } diff --git a/core/chains/evm/txmgr/confirmer_test.go b/core/chains/evm/txmgr/confirmer_test.go index 555ea09ff3..e0070e35b1 100644 --- a/core/chains/evm/txmgr/confirmer_test.go +++ b/core/chains/evm/txmgr/confirmer_test.go @@ -1399,7 +1399,8 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) { etx1 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) nonce++ attempt1_1 := etx1.TxAttempts[0] - dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt1_1) + var dbAttempt txmgr.DbEthTxAttempt + dbAttempt.FromTxAttempt(&attempt1_1) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, tooNew, attempt1_1.ID)) attempt1_2 := newBroadcastLegacyEthTxAttempt(t, etx1.ID) attempt1_2.BroadcastBeforeBlockNum = &onTheMoney @@ -1416,7 +1417,8 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) { etx2 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) nonce++ attempt2_1 := etx2.TxAttempts[0] - dbAttempt = txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt2_1) + dbAttempt = txmgr.DbEthTxAttempt{} + dbAttempt.FromTxAttempt(&attempt2_1) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, tooNew, attempt2_1.ID)) t.Run("returns nothing when the transaction has attempts that are too new", func(t *testing.T) { @@ -1463,13 +1465,15 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) { etx3 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) nonce++ attempt3_1 := etx3.TxAttempts[0] - dbAttempt = txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt3_1) + dbAttempt = txmgr.DbEthTxAttempt{} + dbAttempt.FromTxAttempt(&attempt3_1) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt3_1.ID)) // NOTE: It should ignore qualifying eth_txes from a different address etxOther := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, 0, otherAddress) attemptOther1 := etxOther.TxAttempts[0] - dbAttempt = txmgr.DbEthTxAttemptFromEthTxAttempt(&attemptOther1) + dbAttempt = txmgr.DbEthTxAttempt{} + dbAttempt.FromTxAttempt(&attemptOther1) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attemptOther1.ID)) t.Run("returns the transaction if it is unconfirmed with an attempt that is older than gasBumpThreshold blocks", func(t *testing.T) { @@ -1519,14 +1523,16 @@ func TestEthConfirmer_FindTxsRequiringRebroadcast(t *testing.T) { etx4 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) nonce++ attempt4_1 := etx4.TxAttempts[0] - dbAttempt = txmgr.DbEthTxAttemptFromEthTxAttempt(&attemptOther1) + dbAttempt = txmgr.DbEthTxAttempt{} + dbAttempt.FromTxAttempt(&attempt4_1) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt4_1.ID)) t.Run("ignores pending transactions for another key", func(t *testing.T) { // Re-use etx3 nonce for another key, it should not affect the results for this key etxOther := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, (*etx3.Sequence).Int64(), otherAddress) aOther := etxOther.TxAttempts[0] - dbAttempt = txmgr.DbEthTxAttemptFromEthTxAttempt(&aOther) + dbAttempt = txmgr.DbEthTxAttempt{} + dbAttempt.FromTxAttempt(&aOther) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, aOther.ID)) etxs, err := ec.FindTxsRequiringRebroadcast(testutils.Context(t), lggr, evmFromAddress, currentHead, gasBumpThreshold, 6, 0, &cltest.FixtureChainID) @@ -1659,7 +1665,8 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress, originalBroadcastAt) attempt1 := etx.TxAttempts[0] - dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt1) + var dbAttempt txmgr.DbEthTxAttempt + dbAttempt.FromTxAttempt(&attempt1) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1.ID)) // Send transaction and assume success. @@ -1703,7 +1710,8 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WithConnectivityCheck(t *testing etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastDynamicFeeAttempt(t, txStore, nonce, fromAddress, originalBroadcastAt) attempt1 := etx.TxAttempts[0] - dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt1) + var dbAttempt txmgr.DbEthTxAttempt + dbAttempt.FromTxAttempt(&attempt1) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1.ID)) // Send transaction and assume success. @@ -1974,7 +1982,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { require.Equal(t, txmgrtypes.TxAttemptBroadcast, etx.TxAttempts[3].State) }) - // Mark original tx as confirmed so we won't pick it up any more + // Mark original tx as confirmed, so we won't pick it up anymore pgtest.MustExec(t, db, `UPDATE evm.txes SET state = 'confirmed'`) etx2 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) @@ -2083,7 +2091,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { assert.Equal(t, txmgrtypes.TxAttemptBroadcast, etx2.TxAttempts[2].State) }) - // Original tx is confirmed so we won't pick it up any more + // Original tx is confirmed, so we won't pick it up anymore etx3 := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) nonce++ attempt3_1 := etx3.TxAttempts[0] @@ -2214,7 +2222,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return evmtypes.Nonce(tx.Nonce()) == *etx3.Sequence && gasPrice.Cmp(tx.GasPrice()) == 0 - }), fromAddress).Return(clienttypes.Successful, errors.New("already known")).Once() // we already submitted at this price, now its time to bump and submit again but since we simply resubmitted rather than increasing gas price, geth already knows about this tx + }), fromAddress).Return(clienttypes.Successful, errors.New("already known")).Once() // we already submitted at this price, now it's time to bump and submit again but since we simply resubmitted rather than increasing gas price, geth already knows about this tx // Do the thing require.NoError(t, ec2.RebroadcastWhereNecessary(testutils.Context(t), currentHead)) @@ -2245,7 +2253,7 @@ func TestEthConfirmer_RebroadcastWhereNecessary(t *testing.T) { ethClient.On("SendTransactionReturnCode", mock.Anything, mock.MatchedBy(func(tx *types.Transaction) bool { return evmtypes.Nonce(tx.Nonce()) == *etx3.Sequence && gasPrice.Cmp(tx.GasPrice()) == 0 - }), fromAddress).Return(clienttypes.Successful, errors.New("already known")).Once() // we already submitted at this price, now its time to bump and submit again but since we simply resubmitted rather than increasing gas price, geth already knows about this tx + }), fromAddress).Return(clienttypes.Successful, errors.New("already known")).Once() // we already submitted at this price, now it's time to bump and submit again but since we simply resubmitted rather than increasing gas price, geth already knows about this tx // Do the thing require.NoError(t, ec2.RebroadcastWhereNecessary(testutils.Context(t), currentHead)) @@ -2430,7 +2438,8 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyUnderpriced_ThenGoesTh etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) nonce++ legacyAttempt := etx.TxAttempts[0] - dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&legacyAttempt) + var dbAttempt txmgr.DbEthTxAttempt + dbAttempt.FromTxAttempt(&legacyAttempt) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, legacyAttempt.ID)) // Fail a few times with terminally underpriced @@ -2462,7 +2471,8 @@ func TestEthConfirmer_RebroadcastWhereNecessary_TerminallyUnderpriced_ThenGoesTh etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastDynamicFeeAttempt(t, txStore, nonce, fromAddress) nonce++ dxFeeAttempt := etx.TxAttempts[0] - dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&dxFeeAttempt) + var dbAttempt txmgr.DbEthTxAttempt + dbAttempt.FromTxAttempt(&dxFeeAttempt) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, dxFeeAttempt.ID)) // Fail a few times with terminally underpriced @@ -2513,7 +2523,8 @@ func TestEthConfirmer_RebroadcastWhereNecessary_WhenOutOfEth(t *testing.T) { etx := cltest.MustInsertUnconfirmedEthTxWithBroadcastLegacyAttempt(t, txStore, nonce, fromAddress) nonce++ attempt1_1 := etx.TxAttempts[0] - dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt1_1) + var dbAttempt txmgr.DbEthTxAttempt + dbAttempt.FromTxAttempt(&attempt1_1) require.NoError(t, db.Get(&dbAttempt, `UPDATE evm.tx_attempts SET broadcast_before_block_num=$1 WHERE id=$2 RETURNING *`, oldEnough, attempt1_1.ID)) var attempt1_2 txmgr.TxAttempt diff --git a/core/chains/evm/txmgr/evm_tx_store.go b/core/chains/evm/txmgr/evm_tx_store.go index 4585d86860..52cd50cba3 100644 --- a/core/chains/evm/txmgr/evm_tx_store.go +++ b/core/chains/evm/txmgr/evm_tx_store.go @@ -182,66 +182,62 @@ type DbEthTx struct { InitialBroadcastAt *time.Time } -func DbEthTxFromEthTx(ethTx *Tx) DbEthTx { - tx := DbEthTx{ - ID: ethTx.ID, - FromAddress: ethTx.FromAddress, - ToAddress: ethTx.ToAddress, - EncodedPayload: ethTx.EncodedPayload, - Value: assets.Eth(ethTx.Value), - GasLimit: ethTx.FeeLimit, - Error: ethTx.Error, - BroadcastAt: ethTx.BroadcastAt, - CreatedAt: ethTx.CreatedAt, - State: ethTx.State, - Meta: ethTx.Meta, - Subject: ethTx.Subject, - PipelineTaskRunID: ethTx.PipelineTaskRunID, - MinConfirmations: ethTx.MinConfirmations, - TransmitChecker: ethTx.TransmitChecker, - InitialBroadcastAt: ethTx.InitialBroadcastAt, - } - - if ethTx.ChainID != nil { - tx.EVMChainID = *utils.NewBig(ethTx.ChainID) - } - if ethTx.Sequence != nil { - n := ethTx.Sequence.Int64() - tx.Nonce = &n - } - - return tx -} - -func DbEthTxToEthTx(dbEthTx DbEthTx, evmEthTx *Tx) { - evmEthTx.ID = dbEthTx.ID - if dbEthTx.Nonce != nil { - n := evmtypes.Nonce(*dbEthTx.Nonce) - evmEthTx.Sequence = &n - } - evmEthTx.IdempotencyKey = dbEthTx.IdempotencyKey - evmEthTx.FromAddress = dbEthTx.FromAddress - evmEthTx.ToAddress = dbEthTx.ToAddress - evmEthTx.EncodedPayload = dbEthTx.EncodedPayload - evmEthTx.Value = *dbEthTx.Value.ToInt() - evmEthTx.FeeLimit = dbEthTx.GasLimit - evmEthTx.Error = dbEthTx.Error - evmEthTx.BroadcastAt = dbEthTx.BroadcastAt - evmEthTx.CreatedAt = dbEthTx.CreatedAt - evmEthTx.State = dbEthTx.State - evmEthTx.Meta = dbEthTx.Meta - evmEthTx.Subject = dbEthTx.Subject - evmEthTx.PipelineTaskRunID = dbEthTx.PipelineTaskRunID - evmEthTx.MinConfirmations = dbEthTx.MinConfirmations - evmEthTx.ChainID = dbEthTx.EVMChainID.ToInt() - evmEthTx.TransmitChecker = dbEthTx.TransmitChecker - evmEthTx.InitialBroadcastAt = dbEthTx.InitialBroadcastAt +func (db *DbEthTx) FromTx(tx *Tx) { + db.ID = tx.ID + db.FromAddress = tx.FromAddress + db.ToAddress = tx.ToAddress + db.EncodedPayload = tx.EncodedPayload + db.Value = assets.Eth(tx.Value) + db.GasLimit = tx.FeeLimit + db.Error = tx.Error + db.BroadcastAt = tx.BroadcastAt + db.CreatedAt = tx.CreatedAt + db.State = tx.State + db.Meta = tx.Meta + db.Subject = tx.Subject + db.PipelineTaskRunID = tx.PipelineTaskRunID + db.MinConfirmations = tx.MinConfirmations + db.TransmitChecker = tx.TransmitChecker + db.InitialBroadcastAt = tx.InitialBroadcastAt + + if tx.ChainID != nil { + db.EVMChainID = *utils.NewBig(tx.ChainID) + } + if tx.Sequence != nil { + n := tx.Sequence.Int64() + db.Nonce = &n + } +} + +func (db DbEthTx) ToTx(tx *Tx) { + tx.ID = db.ID + if db.Nonce != nil { + n := evmtypes.Nonce(*db.Nonce) + tx.Sequence = &n + } + tx.IdempotencyKey = db.IdempotencyKey + tx.FromAddress = db.FromAddress + tx.ToAddress = db.ToAddress + tx.EncodedPayload = db.EncodedPayload + tx.Value = *db.Value.ToInt() + tx.FeeLimit = db.GasLimit + tx.Error = db.Error + tx.BroadcastAt = db.BroadcastAt + tx.CreatedAt = db.CreatedAt + tx.State = db.State + tx.Meta = db.Meta + tx.Subject = db.Subject + tx.PipelineTaskRunID = db.PipelineTaskRunID + tx.MinConfirmations = db.MinConfirmations + tx.ChainID = db.EVMChainID.ToInt() + tx.TransmitChecker = db.TransmitChecker + tx.InitialBroadcastAt = db.InitialBroadcastAt } func dbEthTxsToEvmEthTxs(dbEthTxs []DbEthTx) []Tx { evmEthTxs := make([]Tx, len(dbEthTxs)) for i, dbTx := range dbEthTxs { - DbEthTxToEthTx(dbTx, &evmEthTxs[i]) + dbTx.ToTx(&evmEthTxs[i]) } return evmEthTxs } @@ -249,7 +245,7 @@ func dbEthTxsToEvmEthTxs(dbEthTxs []DbEthTx) []Tx { func dbEthTxsToEvmEthTxPtrs(dbEthTxs []DbEthTx, evmEthTxs []*Tx) { for i, dbTx := range dbEthTxs { evmEthTxs[i] = &Tx{} - DbEthTxToEthTx(dbTx, evmEthTxs[i]) + dbTx.ToTx(evmEthTxs[i]) } } @@ -270,29 +266,25 @@ type DbEthTxAttempt struct { GasFeeCap *assets.Wei } -func DbEthTxAttemptFromEthTxAttempt(ethTxAttempt *TxAttempt) DbEthTxAttempt { - dbTx := DbEthTxAttempt{ - ID: ethTxAttempt.ID, - EthTxID: ethTxAttempt.TxID, - GasPrice: ethTxAttempt.TxFee.Legacy, - SignedRawTx: ethTxAttempt.SignedRawTx, - Hash: ethTxAttempt.Hash, - BroadcastBeforeBlockNum: ethTxAttempt.BroadcastBeforeBlockNum, - CreatedAt: ethTxAttempt.CreatedAt, - ChainSpecificGasLimit: ethTxAttempt.ChainSpecificFeeLimit, - TxType: ethTxAttempt.TxType, - GasTipCap: ethTxAttempt.TxFee.DynamicTipCap, - GasFeeCap: ethTxAttempt.TxFee.DynamicFeeCap, - } +func (db *DbEthTxAttempt) FromTxAttempt(attempt *TxAttempt) { + db.ID = attempt.ID + db.EthTxID = attempt.TxID + db.GasPrice = attempt.TxFee.Legacy + db.SignedRawTx = attempt.SignedRawTx + db.Hash = attempt.Hash + db.BroadcastBeforeBlockNum = attempt.BroadcastBeforeBlockNum + db.CreatedAt = attempt.CreatedAt + db.ChainSpecificGasLimit = attempt.ChainSpecificFeeLimit + db.TxType = attempt.TxType + db.GasTipCap = attempt.TxFee.DynamicTipCap + db.GasFeeCap = attempt.TxFee.DynamicFeeCap // handle state naming difference between generic + EVM - if ethTxAttempt.State == txmgrtypes.TxAttemptInsufficientFunds { - dbTx.State = "insufficient_eth" + if attempt.State == txmgrtypes.TxAttemptInsufficientFunds { + db.State = "insufficient_eth" } else { - dbTx.State = ethTxAttempt.State.String() + db.State = attempt.State.String() } - - return dbTx } func DbEthTxAttemptStateToTxAttemptState(state string) txmgrtypes.TxAttemptState { @@ -302,27 +294,27 @@ func DbEthTxAttemptStateToTxAttemptState(state string) txmgrtypes.TxAttemptState return txmgrtypes.NewTxAttemptState(state) } -func DbEthTxAttemptToEthTxAttempt(dbEthTxAttempt DbEthTxAttempt, evmAttempt *TxAttempt) { - evmAttempt.ID = dbEthTxAttempt.ID - evmAttempt.TxID = dbEthTxAttempt.EthTxID - evmAttempt.SignedRawTx = dbEthTxAttempt.SignedRawTx - evmAttempt.Hash = dbEthTxAttempt.Hash - evmAttempt.BroadcastBeforeBlockNum = dbEthTxAttempt.BroadcastBeforeBlockNum - evmAttempt.State = DbEthTxAttemptStateToTxAttemptState(dbEthTxAttempt.State) - evmAttempt.CreatedAt = dbEthTxAttempt.CreatedAt - evmAttempt.ChainSpecificFeeLimit = dbEthTxAttempt.ChainSpecificGasLimit - evmAttempt.TxType = dbEthTxAttempt.TxType - evmAttempt.TxFee = gas.EvmFee{ - Legacy: dbEthTxAttempt.GasPrice, - DynamicTipCap: dbEthTxAttempt.GasTipCap, - DynamicFeeCap: dbEthTxAttempt.GasFeeCap, +func (db DbEthTxAttempt) ToTxAttempt(attempt *TxAttempt) { + attempt.ID = db.ID + attempt.TxID = db.EthTxID + attempt.SignedRawTx = db.SignedRawTx + attempt.Hash = db.Hash + attempt.BroadcastBeforeBlockNum = db.BroadcastBeforeBlockNum + attempt.State = DbEthTxAttemptStateToTxAttemptState(db.State) + attempt.CreatedAt = db.CreatedAt + attempt.ChainSpecificFeeLimit = db.ChainSpecificGasLimit + attempt.TxType = db.TxType + attempt.TxFee = gas.EvmFee{ + Legacy: db.GasPrice, + DynamicTipCap: db.GasTipCap, + DynamicFeeCap: db.GasFeeCap, } } func dbEthTxAttemptsToEthTxAttempts(dbEthTxAttempt []DbEthTxAttempt) []TxAttempt { evmEthTxAttempt := make([]TxAttempt, len(dbEthTxAttempt)) for i, dbTxAttempt := range dbEthTxAttempt { - DbEthTxAttemptToEthTxAttempt(dbTxAttempt, &evmEthTxAttempt[i]) + dbTxAttempt.ToTxAttempt(&evmEthTxAttempt[i]) } return evmEthTxAttempt } @@ -379,7 +371,7 @@ func (o *evmTxStore) preloadTxAttempts(txs []Tx) error { for i, tx := range txs { if tx.ID == dbAttempt.EthTxID { var attempt TxAttempt - DbEthTxAttemptToEthTxAttempt(dbAttempt, &attempt) + dbAttempt.ToTxAttempt(&attempt) txs[i].TxAttempts = append(txs[i].TxAttempts, attempt) } } @@ -405,7 +397,7 @@ func (o *evmTxStore) PreloadTxes(attempts []TxAttempt, qopts ...pg.QOpt) error { } for _, dbEtx := range dbEthTxs { etx := ethTxM[dbEtx.ID] - DbEthTxToEthTx(dbEtx, &etx) + dbEtx.ToTx(&etx) ethTxM[etx.ID] = etx } for i, attempt := range attempts { @@ -475,7 +467,7 @@ func (o *evmTxStore) FindTxAttempt(hash common.Hash) (*TxAttempt, error) { } // reuse the preload var attempt TxAttempt - DbEthTxAttemptToEthTxAttempt(dbTxAttempt, &attempt) + dbTxAttempt.ToTxAttempt(&attempt) attempts := []TxAttempt{attempt} err := o.PreloadTxes(attempts) return &attempts[0], err @@ -502,7 +494,7 @@ func (o *evmTxStore) FindTxByHash(hash common.Hash) (*Tx, error) { }, pg.OptReadOnlyTx()) var etx Tx - DbEthTxToEthTx(dbEtx, &etx) + dbEtx.ToTx(&etx) return &etx, pkgerrors.Wrap(err, "FindEthTxByHash failed") } @@ -514,17 +506,19 @@ func (o *evmTxStore) InsertTx(etx *Tx) error { const insertEthTxSQL = `INSERT INTO evm.txes (nonce, from_address, to_address, encoded_payload, value, gas_limit, error, broadcast_at, initial_broadcast_at, created_at, state, meta, subject, pipeline_task_run_id, min_confirmations, evm_chain_id, transmit_checker) VALUES ( :nonce, :from_address, :to_address, :encoded_payload, :value, :gas_limit, :error, :broadcast_at, :initial_broadcast_at, :created_at, :state, :meta, :subject, :pipeline_task_run_id, :min_confirmations, :evm_chain_id, :transmit_checker ) RETURNING *` - dbTx := DbEthTxFromEthTx(etx) + var dbTx DbEthTx + dbTx.FromTx(etx) err := o.q.GetNamed(insertEthTxSQL, &dbTx, &dbTx) - DbEthTxToEthTx(dbTx, etx) + dbTx.ToTx(etx) return pkgerrors.Wrap(err, "InsertTx failed") } // InsertTxAttempt inserts a new txAttempt into the database func (o *evmTxStore) InsertTxAttempt(attempt *TxAttempt) error { - dbTxAttempt := DbEthTxAttemptFromEthTxAttempt(attempt) + var dbTxAttempt DbEthTxAttempt + dbTxAttempt.FromTxAttempt(attempt) err := o.q.GetNamed(insertIntoEthTxAttemptsQuery, &dbTxAttempt, &dbTxAttempt) - DbEthTxAttemptToEthTxAttempt(dbTxAttempt, attempt) + dbTxAttempt.ToTxAttempt(attempt) return pkgerrors.Wrap(err, "InsertTxAttempt failed") } @@ -548,7 +542,7 @@ func (o *evmTxStore) FindTxWithAttempts(etxID int64) (etx Tx, err error) { if err = tx.Get(&dbEtx, `SELECT * FROM evm.txes WHERE id = $1 ORDER BY created_at ASC, id ASC`, etxID); err != nil { return pkgerrors.Wrapf(err, "failed to find eth_tx with id %d", etxID) } - DbEthTxToEthTx(dbEtx, &etx) + dbEtx.ToTx(&etx) if err = o.LoadTxAttempts(&etx, pg.WithQueryer(tx)); err != nil { return pkgerrors.Wrapf(err, "failed to load evm.tx_attempts for eth_tx with id %d", etxID) } @@ -591,7 +585,7 @@ func (o *evmTxStore) LoadTxesAttempts(etxs []*Tx, qopts ...pg.QOpt) error { for _, dbAttempt := range dbTxAttempts { etx := ethTxesM[dbAttempt.EthTxID] var attempt TxAttempt - DbEthTxAttemptToEthTxAttempt(dbAttempt, &attempt) + dbAttempt.ToTxAttempt(&attempt) etx.TxAttempts = append(etx.TxAttempts, attempt) } return nil @@ -919,7 +913,7 @@ func (o *evmTxStore) FindTxWithIdempotencyKey(idempotencyKey string, chainID *bi return nil, pkgerrors.Wrap(err, "FindTxWithIdempotencyKey failed to load evm.txes") } etx = new(Tx) - DbEthTxToEthTx(dbEtx, etx) + dbEtx.ToTx(etx) return } @@ -934,7 +928,7 @@ SELECT * FROM evm.txes WHERE from_address = $1 AND nonce = $2 AND state IN ('con if err != nil { return pkgerrors.Wrap(err, "FindEthTxWithNonce failed to load evm.txes") } - DbEthTxToEthTx(dbEtx, etx) + dbEtx.ToTx(etx) err = o.LoadTxAttempts(etx, pg.WithQueryer(tx)) return pkgerrors.Wrap(err, "FindEthTxWithNonce failed to load evm.tx_attempts") }, pg.OptReadOnlyTx()) @@ -1008,7 +1002,8 @@ ORDER BY nonce ASC func saveAttemptWithNewState(q pg.Queryer, timeout time.Duration, logger logger.Logger, attempt TxAttempt, broadcastAt time.Time) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) - dbAttempt := DbEthTxAttemptFromEthTxAttempt(&attempt) + var dbAttempt DbEthTxAttempt + dbAttempt.FromTxAttempt(&attempt) defer cancel() return pg.SqlxTransaction(ctx, q, logger, func(tx pg.Queryer) error { // In case of null broadcast_at (shouldn't happen) we don't want to @@ -1075,7 +1070,8 @@ func (o *evmTxStore) SaveInProgressAttempt(attempt *TxAttempt) error { if attempt.State != txmgrtypes.TxAttemptInProgress { return errors.New("SaveInProgressAttempt failed: attempt state must be in_progress") } - dbAttempt := DbEthTxAttemptFromEthTxAttempt(attempt) + var dbAttempt DbEthTxAttempt + dbAttempt.FromTxAttempt(attempt) // Insert is the usual mode because the attempt is new if attempt.ID == 0 { query, args, e := o.q.BindNamed(insertIntoEthTxAttemptsQuery, &dbAttempt) @@ -1083,7 +1079,7 @@ func (o *evmTxStore) SaveInProgressAttempt(attempt *TxAttempt) error { return pkgerrors.Wrap(e, "SaveInProgressAttempt failed to BindNamed") } e = o.q.Get(&dbAttempt, query, args...) - DbEthTxAttemptToEthTxAttempt(dbAttempt, attempt) + dbAttempt.ToTxAttempt(attempt) return pkgerrors.Wrap(e, "SaveInProgressAttempt failed to insert into evm.tx_attempts") } // Update only applies to case of insufficient eth and simply changes the state to in_progress @@ -1265,13 +1261,14 @@ func (o *evmTxStore) SaveReplacementInProgressAttempt(oldAttempt TxAttempt, repl if _, err := tx.Exec(`DELETE FROM evm.tx_attempts WHERE id=$1`, oldAttempt.ID); err != nil { return pkgerrors.Wrap(err, "saveReplacementInProgressAttempt failed to delete from evm.tx_attempts") } - dbAttempt := DbEthTxAttemptFromEthTxAttempt(replacementAttempt) + var dbAttempt DbEthTxAttempt + dbAttempt.FromTxAttempt(replacementAttempt) query, args, e := tx.BindNamed(insertIntoEthTxAttemptsQuery, &dbAttempt) if e != nil { return pkgerrors.Wrap(e, "saveReplacementInProgressAttempt failed to BindNamed") } e = tx.Get(&dbAttempt, query, args...) - DbEthTxAttemptToEthTxAttempt(dbAttempt, replacementAttempt) + dbAttempt.ToTxAttempt(replacementAttempt) return pkgerrors.Wrap(e, "saveReplacementInProgressAttempt failed to insert replacement attempt") }) } @@ -1281,7 +1278,7 @@ func (o *evmTxStore) FindNextUnstartedTransactionFromAddress(etx *Tx, fromAddres qq := o.q.WithOpts(qopts...) var dbEtx DbEthTx err := qq.Get(&dbEtx, `SELECT * FROM evm.txes WHERE from_address = $1 AND state = 'unstarted' AND evm_chain_id = $2 ORDER BY value ASC, created_at ASC, id ASC`, fromAddress, chainID.String()) - DbEthTxToEthTx(dbEtx, etx) + dbEtx.ToTx(etx) return pkgerrors.Wrap(err, "failed to FindNextUnstartedTransactionFromAddress") } @@ -1302,9 +1299,10 @@ func (o *evmTxStore) UpdateTxFatalError(etx *Tx, qopts ...pg.QOpt) error { if _, err := tx.Exec(`DELETE FROM evm.tx_attempts WHERE eth_tx_id = $1`, etx.ID); err != nil { return pkgerrors.Wrapf(err, "saveFatallyErroredTransaction failed to delete eth_tx_attempt with eth_tx.ID %v", etx.ID) } - dbEtx := DbEthTxFromEthTx(etx) + var dbEtx DbEthTx + dbEtx.FromTx(etx) err := pkgerrors.Wrap(tx.Get(&dbEtx, `UPDATE evm.txes SET state=$1, error=$2, broadcast_at=NULL, initial_broadcast_at=NULL, nonce=NULL WHERE id=$3 RETURNING *`, etx.State, etx.Error, etx.ID), "saveFatallyErroredTransaction failed to save eth_tx") - DbEthTxToEthTx(dbEtx, etx) + dbEtx.ToTx(etx) return err }) } @@ -1336,12 +1334,14 @@ func (o *evmTxStore) UpdateTxAttemptInProgressToBroadcast(etx *Tx, attempt TxAtt if err := incrNextNonceCallback(tx); err != nil { return pkgerrors.Wrap(err, "SaveEthTxAttempt failed on incrNextNonceCallback") } - dbEtx := DbEthTxFromEthTx(etx) + var dbEtx DbEthTx + dbEtx.FromTx(etx) if err := tx.Get(&dbEtx, `UPDATE evm.txes SET state=$1, error=$2, broadcast_at=$3, initial_broadcast_at=$4 WHERE id = $5 RETURNING *`, dbEtx.State, dbEtx.Error, dbEtx.BroadcastAt, dbEtx.InitialBroadcastAt, dbEtx.ID); err != nil { return pkgerrors.Wrap(err, "SaveEthTxAttempt failed to save eth_tx") } - DbEthTxToEthTx(dbEtx, etx) - dbAttempt := DbEthTxAttemptFromEthTxAttempt(&attempt) + dbEtx.ToTx(etx) + var dbAttempt DbEthTxAttempt + dbAttempt.FromTxAttempt(&attempt) if err := tx.Get(&dbAttempt, `UPDATE evm.tx_attempts SET state = $1 WHERE id = $2 RETURNING *`, dbAttempt.State, dbAttempt.ID); err != nil { return pkgerrors.Wrap(err, "SaveEthTxAttempt failed to save eth_tx_attempt") } @@ -1380,7 +1380,8 @@ func (o *evmTxStore) UpdateTxUnstartedToInProgress(etx *Tx, attempt *TxAttempt, return err } - dbAttempt := DbEthTxAttemptFromEthTxAttempt(attempt) + var dbAttempt DbEthTxAttempt + dbAttempt.FromTxAttempt(attempt) query, args, e := tx.BindNamed(insertIntoEthTxAttemptsQuery, &dbAttempt) if e != nil { return pkgerrors.Wrap(e, "failed to BindNamed") @@ -1397,10 +1398,11 @@ func (o *evmTxStore) UpdateTxUnstartedToInProgress(etx *Tx, attempt *TxAttempt, return pkgerrors.Wrap(err, "UpdateTxUnstartedToInProgress failed to create eth_tx_attempt") } } - DbEthTxAttemptToEthTxAttempt(dbAttempt, attempt) - dbEtx := DbEthTxFromEthTx(etx) + dbAttempt.ToTxAttempt(attempt) + var dbEtx DbEthTx + dbEtx.FromTx(etx) err = tx.Get(&dbEtx, `UPDATE evm.txes SET nonce=$1, state=$2, broadcast_at=$3, initial_broadcast_at=$4 WHERE id=$5 RETURNING *`, etx.Sequence, etx.State, etx.BroadcastAt, etx.InitialBroadcastAt, etx.ID) - DbEthTxToEthTx(dbEtx, etx) + dbEtx.ToTx(etx) return pkgerrors.Wrap(err, "UpdateTxUnstartedToInProgress failed to update eth_tx") }) } @@ -1424,7 +1426,7 @@ func (o *evmTxStore) GetTxInProgress(fromAddress common.Address, qopts ...pg.QOp } else if err != nil { return pkgerrors.Wrap(err, "GetTxInProgress failed while loading eth tx") } - DbEthTxToEthTx(dbEtx, etx) + dbEtx.ToTx(etx) if err = o.LoadTxAttempts(etx, pg.WithQueryer(tx)); err != nil { return pkgerrors.Wrap(err, "GetTxInProgress failed while loading EthTxAttempts") } @@ -1536,7 +1538,7 @@ RETURNING "txes".* return nil }) var etx Tx - DbEthTxToEthTx(dbEtx, &etx) + dbEtx.ToTx(&etx) return etx, err } diff --git a/core/chains/evm/txmgr/evm_tx_store_test.go b/core/chains/evm/txmgr/evm_tx_store_test.go index c4837f81e8..913652b7c8 100644 --- a/core/chains/evm/txmgr/evm_tx_store_test.go +++ b/core/chains/evm/txmgr/evm_tx_store_test.go @@ -1100,7 +1100,8 @@ func TestORM_LoadEthTxesAttempts(t *testing.T) { q := pg.NewQ(db, logger.TestLogger(t), cfg.Database()) newAttempt := cltest.NewDynamicFeeEthTxAttempt(t, etx.ID) - dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&newAttempt) + var dbAttempt txmgr.DbEthTxAttempt + dbAttempt.FromTxAttempt(&newAttempt) err := q.Transaction(func(tx pg.Queryer) error { const insertEthTxAttemptSQL = `INSERT INTO evm.tx_attempts (eth_tx_id, gas_price, signed_raw_tx, hash, broadcast_before_block_num, state, created_at, chain_specific_gas_limit, tx_type, gas_tip_cap, gas_fee_cap) VALUES ( :eth_tx_id, :gas_price, :signed_raw_tx, :hash, :broadcast_before_block_num, :state, NOW(), :chain_specific_gas_limit, :tx_type, :gas_tip_cap, :gas_fee_cap diff --git a/core/chains/evm/txmgr/transmitchecker.go b/core/chains/evm/txmgr/transmitchecker.go index 4569063d63..969e789031 100644 --- a/core/chains/evm/txmgr/transmitchecker.go +++ b/core/chains/evm/txmgr/transmitchecker.go @@ -19,7 +19,7 @@ import ( evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" v1 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface" 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/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/utils" bigmath "github.com/smartcontractkit/chainlink/v2/core/utils/big_math" @@ -84,7 +84,7 @@ func (c *CheckerFactory) BuildChecker(spec TransmitCheckerSpec) (TransmitChecker if spec.VRFCoordinatorAddress == nil { return nil, errors.Errorf("malformed checker, expected non-nil VRFCoordinatorAddress, got: %v", spec) } - coord, err := v2plus.NewVRFCoordinatorV2Plus(*spec.VRFCoordinatorAddress, c.Client) + coord, err := vrf_coordinator_v2plus_interface.NewIVRFCoordinatorV2PlusInternal(*spec.VRFCoordinatorAddress, c.Client) if err != nil { return nil, errors.Wrapf(err, "failed to create VRF V2 coordinator plus at address %v", spec.VRFCoordinatorAddress) diff --git a/core/cmd/evm_transaction_commands_test.go b/core/cmd/evm_transaction_commands_test.go index f213aefb15..eb421b0396 100644 --- a/core/cmd/evm_transaction_commands_test.go +++ b/core/cmd/evm_transaction_commands_test.go @@ -181,7 +181,7 @@ func TestShell_SendEther_From_Txm(t *testing.T) { assert.Equal(t, dbEvmTx.Value.String(), output.Value) assert.Equal(t, fmt.Sprintf("%d", *dbEvmTx.Nonce), output.Nonce) - dbEvmTxAttempt := txmgr.DbEthTxAttempt{} + var dbEvmTxAttempt txmgr.DbEthTxAttempt require.NoError(t, db.Get(&dbEvmTxAttempt, `SELECT * FROM evm.tx_attempts`)) assert.Equal(t, dbEvmTxAttempt.Hash, output.Hash) } @@ -246,7 +246,7 @@ func TestShell_SendEther_From_Txm_WEI(t *testing.T) { assert.Equal(t, dbEvmTx.Value.String(), output.Value) assert.Equal(t, fmt.Sprintf("%d", *dbEvmTx.Nonce), output.Nonce) - dbEvmTxAttempt := txmgr.DbEthTxAttempt{} + var dbEvmTxAttempt txmgr.DbEthTxAttempt require.NoError(t, db.Get(&dbEvmTxAttempt, `SELECT * FROM evm.tx_attempts`)) assert.Equal(t, dbEvmTxAttempt.Hash, output.Hash) } diff --git a/core/cmd/jobs_commands_test.go b/core/cmd/jobs_commands_test.go index 29d0d8da70..57489ccb0f 100644 --- a/core/cmd/jobs_commands_test.go +++ b/core/cmd/jobs_commands_test.go @@ -3,9 +3,11 @@ package cmd_test import ( "bytes" "flag" + "fmt" "testing" "time" + "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/urfave/cli" @@ -293,6 +295,26 @@ func TestJob_ToRows(t *testing.T) { }, job.ToRows()) } +const directRequestSpecTemplate = ` +type = "directrequest" +schemaVersion = 1 +evmChainID = "0" +name = "example eth request event spec" +contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C" +externalJobID = "%s" +observationSource = """ + ds1 [type=http method=GET url="http://example.com" allowunrestrictednetworkaccess="true"]; + ds1_merge [type=merge left="{}"] + ds1_parse [type=jsonparse path="USD"]; + ds1_multiply [type=multiply times=100]; + ds1 -> ds1_parse -> ds1_multiply; +""" +` + +func getDirectRequestSpec() string { + return fmt.Sprintf(directRequestSpecTemplate, uuid.New()) +} + func TestShell_ListFindJobs(t *testing.T) { t.Parallel() @@ -305,7 +327,7 @@ func TestShell_ListFindJobs(t *testing.T) { fs := flag.NewFlagSet("", flag.ExitOnError) cltest.FlagSetApplyFromAction(client.CreateJob, fs, "") - require.NoError(t, fs.Parse([]string{"../testdata/tomlspecs/direct-request-spec.toml"})) + require.NoError(t, fs.Parse([]string{getDirectRequestSpec()})) err := client.CreateJob(cli.NewContext(nil, fs, nil)) require.NoError(t, err) @@ -331,7 +353,7 @@ func TestShell_ShowJob(t *testing.T) { fs := flag.NewFlagSet("", flag.ExitOnError) cltest.FlagSetApplyFromAction(client.CreateJob, fs, "") - require.NoError(t, fs.Parse([]string{"../testdata/tomlspecs/direct-request-spec.toml"})) + require.NoError(t, fs.Parse([]string{getDirectRequestSpec()})) err := client.CreateJob(cli.NewContext(nil, fs, nil)) require.NoError(t, err) @@ -400,7 +422,7 @@ func TestShell_DeleteJob(t *testing.T) { fs := flag.NewFlagSet("", flag.ExitOnError) cltest.FlagSetApplyFromAction(client.CreateJob, fs, "") - require.NoError(t, fs.Parse([]string{"../testdata/tomlspecs/direct-request-spec.toml"})) + require.NoError(t, fs.Parse([]string{getDirectRequestSpec()})) err := client.CreateJob(cli.NewContext(nil, fs, nil)) require.NoError(t, err) diff --git a/core/cmd/shell.go b/core/cmd/shell.go index b9c031fd8b..8532f2f543 100644 --- a/core/cmd/shell.go +++ b/core/cmd/shell.go @@ -109,14 +109,9 @@ func (s *Shell) errorOut(err error) cli.ExitCoder { func (s *Shell) configExitErr(validateFn func() error) cli.ExitCoder { err := validateFn() if err != nil { - if err.Error() != "invalid secrets: Database.AllowSimplePasswords: invalid value (true): insecure configs are not allowed on secure builds" { - fmt.Println("Invalid configuration:", err) - fmt.Println() - return s.errorOut(errors.New("invalid configuration")) - } - fmt.Printf("Notification for upcoming configuration change: %v\n", err) - fmt.Println("This configuration will be disallowed in future production releases.") + fmt.Println("Invalid configuration:", err) fmt.Println() + return s.errorOut(errors.New("invalid configuration")) } return nil } @@ -133,8 +128,7 @@ type ChainlinkAppFactory struct{} func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.GeneralConfig, appLggr logger.Logger, db *sqlx.DB) (app chainlink.Application, err error) { initGlobals(cfg.Prometheus()) - // TODO TO BE REMOVED IN v2.7.0 - err = evmChainIDMigration(cfg, db.DB, appLggr) + err = migrate.SetMigrationENVVars(cfg) if err != nil { return nil, err } @@ -154,15 +148,13 @@ func (n ChainlinkAppFactory) NewApplication(ctx context.Context, cfg chainlink.G // 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}, + ChainOpts: evm.ChainOpts{AppConfig: cfg, EventBroadcaster: eventBroadcaster, MailMon: mailMon, DB: db}, } // evm always enabled for backward compatibility // TODO BCF-2510 this needs to change in order to clear the path for EVM extraction @@ -301,44 +293,6 @@ func takeBackupIfVersionUpgrade(dbUrl url.URL, rootDir string, cfg periodicbacku return err } -// evmChainIDMigration TODO TO BE REMOVED IN v2.7.0. This is a helper function for evmChainID 0195 migration in v2.6.0 only, so that we don't have to inject evmChainID into goose. -func evmChainIDMigration(generalConfig chainlink.GeneralConfig, db *sql.DB, lggr logger.Logger) error { - migrationVer, err := migrate.Current(db, lggr) - if err != nil { - return err - } - if migrationVer != 194 { - return nil - } - - if generalConfig.EVMEnabled() { - if generalConfig.EVMConfigs() == nil { - return errors.New("evm configs are missing") - } - if generalConfig.EVMConfigs()[0] == nil { - return errors.New("evm config is nil") - } - updateQueries := []string{ - `UPDATE direct_request_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, - `UPDATE flux_monitor_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, - `UPDATE ocr_oracle_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, - `UPDATE keeper_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, - `UPDATE vrf_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, - `UPDATE blockhash_store_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, - `UPDATE block_header_feeder_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, - } - - chainID := generalConfig.EVMConfigs()[0].ChainID.String() - for i := range updateQueries { - _, err := db.Exec(updateQueries[i], chainID) - if err != nil { - return errors.Wrap(err, "failed to set missing evm chain ids") - } - } - } - return nil -} - // Runner implements the Run method. type Runner interface { Run(context.Context, chainlink.Application) error diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 26c0b5ed80..372aad0138 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -294,10 +294,7 @@ func (s *Shell) runNode(c *cli.Context) error { err := s.Config.Validate() if err != nil { - if err.Error() != "invalid secrets: Database.AllowSimplePasswords: invalid value (true): insecure configs are not allowed on secure builds" { - return errors.Wrap(err, "config validation failed") - } - lggr.Errorf("Notification for upcoming configuration change: %v", err) + return errors.Wrap(err, "config validation failed") } lggr.Infow(fmt.Sprintf("Starting Chainlink Node %s at commit %s", static.Version, static.Sha), "Version", static.Version, "SHA", static.Sha) @@ -622,10 +619,7 @@ func (s *Shell) RebroadcastTransactions(c *cli.Context) (err error) { err = s.Config.Validate() if err != nil { - if err.Error() != "invalid secrets: Database.AllowSimplePasswords: invalid value (true): insecure configs are not allowed on secure builds" { - return s.errorOut(fmt.Errorf("error validating configuration: %+v", err)) - } - lggr.Errorf("Notification for required upcoming configuration change: %v", err) + return s.errorOut(fmt.Errorf("error validating configuration: %+v", err)) } err = keyStore.Unlock(s.Config.Password().Keystore()) @@ -712,7 +706,7 @@ func (s *Shell) validateDB(c *cli.Context) error { } // ResetDatabase drops, creates and migrates the database specified by CL_DATABASE_URL or Database.URL -// in secrets TOML. This is useful to setup the database for testing +// in secrets TOML. This is useful to set up the database for testing func (s *Shell) ResetDatabase(c *cli.Context) error { cfg := s.Config.Database() parsed := cfg.URL() @@ -819,7 +813,7 @@ func dropDanglingTestDBs(lggr logger.Logger, db *sqlx.DB) (err error) { return } -// PrepareTestDatabase calls ResetDatabase then loads fixtures required for local +// PrepareTestDatabaseUserOnly calls ResetDatabase then loads only user fixtures required for local // testing against testnets. Does not include fake chain fixtures. func (s *Shell) PrepareTestDatabaseUserOnly(c *cli.Context) error { if err := s.ResetDatabase(c); err != nil { @@ -840,19 +834,7 @@ func (s *Shell) MigrateDatabase(_ *cli.Context) error { return s.errorOut(errDBURLMissing) } - // TODO TO BE REMOVED IN v2.7.0 - db, err := sql.Open(string(dialects.Postgres), parsed.String()) - if err != nil { - return fmt.Errorf("unable to open postgres database for evmChainID helper migration: %+v", err) - } - defer func() { - if cerr := db.Close(); cerr != nil { - err = multierr.Append(err, cerr) - } - }() - - // TODO TO BE REMOVED IN v2.7.0 - err = evmChainIDMigration(s.Config, db, s.Logger) + err := migrate.SetMigrationENVVars(s.Config) if err != nil { return err } @@ -864,7 +846,7 @@ func (s *Shell) MigrateDatabase(_ *cli.Context) error { return nil } -// VersionDatabase displays the current database version. +// RollbackDatabase rolls back the database via down migrations. func (s *Shell) RollbackDatabase(c *cli.Context) error { var version null.Int if c.Args().Present() { diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index 8d2b5f1fab..691e5faa92 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -42,13 +42,11 @@ import ( 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, + ChainOpts: opts.ChainOpts, CSAETHKeystore: ks, })) if err != nil { @@ -87,12 +85,12 @@ func TestShell_RunNodeWithPasswords(t *testing.T) { opts := evm.ChainRelayExtenderConfig{ Logger: lggr, - DB: db, KeyStore: keyStore.Eth(), - RelayerConfig: &evm.RelayerConfig{ + ChainOpts: evm.ChainOpts{ AppConfig: cfg, EventBroadcaster: pg.NewNullEventBroadcaster(), MailMon: &utils.MailboxMonitor{}, + DB: db, }, } testRelayers := genTestEVMRelayers(t, opts, keyStore) @@ -191,13 +189,12 @@ func TestShell_RunNodeWithAPICredentialsFile(t *testing.T) { lggr := logger.TestLogger(t) opts := evm.ChainRelayExtenderConfig{ Logger: lggr, - DB: db, KeyStore: keyStore.Eth(), - RelayerConfig: &evm.RelayerConfig{ + ChainOpts: evm.ChainOpts{ AppConfig: cfg, EventBroadcaster: pg.NewNullEventBroadcaster(), - - MailMon: &utils.MailboxMonitor{}, + MailMon: &utils.MailboxMonitor{}, + DB: db, }, } testRelayers := genTestEVMRelayers(t, opts, keyStore) diff --git a/core/cmd/shell_remote_test.go b/core/cmd/shell_remote_test.go index 83686443fa..8fb1a9fb64 100644 --- a/core/cmd/shell_remote_test.go +++ b/core/cmd/shell_remote_test.go @@ -257,17 +257,20 @@ func TestShell_DestroyExternalInitiator_NotFound(t *testing.T) { func TestShell_RemoteLogin(t *testing.T) { app := startNewApplicationV2(t, nil) + orm := app.SessionORM() + + u := cltest.NewUserWithSession(t, orm) tests := []struct { name, file string email, pwd string wantError bool }{ - {"success prompt", "", cltest.APIEmailAdmin, cltest.Password, false}, + {"success prompt", "", u.Email, cltest.Password, false}, {"success file", "../internal/fixtures/apicredentials", "", "", false}, {"failure prompt", "", "wrong@email.com", "wrongpwd", true}, {"failure file", "/tmp/doesntexist", "", "", true}, - {"failure file w correct prompt", "/tmp/doesntexist", cltest.APIEmailAdmin, cltest.Password, true}, + {"failure file w correct prompt", "/tmp/doesntexist", u.Email, cltest.Password, true}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -297,7 +300,8 @@ func TestShell_RemoteBuildCompatibility(t *testing.T) { t.Parallel() app := startNewApplicationV2(t, nil) - enteredStrings := []string{cltest.APIEmailAdmin, cltest.Password} + u := cltest.NewUserWithSession(t, app.SessionORM()) + enteredStrings := []string{u.Email, cltest.Password} prompter := &cltest.MockCountingPrompter{T: t, EnteredStrings: append(enteredStrings, enteredStrings...)} client := app.NewAuthenticatingShell(prompter) @@ -335,6 +339,7 @@ func TestShell_CheckRemoteBuildCompatibility(t *testing.T) { t.Parallel() app := startNewApplicationV2(t, nil) + u := cltest.NewUserWithSession(t, app.SessionORM()) tests := []struct { name string remoteVersion, remoteSha string @@ -349,7 +354,7 @@ func TestShell_CheckRemoteBuildCompatibility(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - enteredStrings := []string{cltest.APIEmailAdmin, cltest.Password} + enteredStrings := []string{u.Email, cltest.Password} prompter := &cltest.MockCountingPrompter{T: t, EnteredStrings: enteredStrings} client := app.NewAuthenticatingShell(prompter) @@ -410,8 +415,9 @@ func TestShell_ChangePassword(t *testing.T) { t.Parallel() app := startNewApplicationV2(t, nil) + u := cltest.NewUserWithSession(t, app.SessionORM()) - enteredStrings := []string{cltest.APIEmailAdmin, cltest.Password} + enteredStrings := []string{u.Email, cltest.Password} prompter := &cltest.MockCountingPrompter{T: t, EnteredStrings: enteredStrings} client := app.NewAuthenticatingShell(prompter) @@ -459,7 +465,8 @@ func TestShell_Profile_InvalidSecondsParam(t *testing.T) { t.Parallel() app := startNewApplicationV2(t, nil) - enteredStrings := []string{cltest.APIEmailAdmin, cltest.Password} + u := cltest.NewUserWithSession(t, app.SessionORM()) + enteredStrings := []string{u.Email, cltest.Password} prompter := &cltest.MockCountingPrompter{T: t, EnteredStrings: enteredStrings} client := app.NewAuthenticatingShell(prompter) @@ -489,7 +496,8 @@ func TestShell_Profile(t *testing.T) { t.Parallel() app := startNewApplicationV2(t, nil) - enteredStrings := []string{cltest.APIEmailAdmin, cltest.Password} + u := cltest.NewUserWithSession(t, app.SessionORM()) + enteredStrings := []string{u.Email, cltest.Password} prompter := &cltest.MockCountingPrompter{T: t, EnteredStrings: enteredStrings} client := app.NewAuthenticatingShell(prompter) @@ -656,7 +664,7 @@ func TestShell_AutoLogin(t *testing.T) { require.NoError(t, err) // Expire the session and then try again - pgtest.MustExec(t, app.GetSqlxDB(), "TRUNCATE sessions") + pgtest.MustExec(t, app.GetSqlxDB(), "delete from sessions where email = $1", user.Email) err = client.ListJobs(cli.NewContext(nil, fs, nil)) require.NoError(t, err) } diff --git a/core/cmd/shell_test.go b/core/cmd/shell_test.go index 45192392f6..a8190a0595 100644 --- a/core/cmd/shell_test.go +++ b/core/cmd/shell_test.go @@ -33,13 +33,16 @@ import ( func TestTerminalCookieAuthenticator_AuthenticateWithoutSession(t *testing.T) { t.Parallel() + app := cltest.NewApplicationEVMDisabled(t) + u := cltest.NewUserWithSession(t, app.SessionORM()) + tests := []struct { name, email, pwd string }{ {"bad email", "notreal", cltest.Password}, - {"bad pwd", cltest.APIEmailAdmin, "mostcommonwrongpwdever"}, + {"bad pwd", u.Email, "mostcommonwrongpwdever"}, {"bad both", "notreal", "mostcommonwrongpwdever"}, - {"correct", cltest.APIEmailAdmin, cltest.Password}, + {"correct", u.Email, cltest.Password}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -63,14 +66,16 @@ func TestTerminalCookieAuthenticator_AuthenticateWithSession(t *testing.T) { app := cltest.NewApplicationEVMDisabled(t) require.NoError(t, app.Start(testutils.Context(t))) + u := cltest.NewUserWithSession(t, app.SessionORM()) + tests := []struct { name, email, pwd string wantError bool }{ {"bad email", "notreal", cltest.Password, true}, - {"bad pwd", cltest.APIEmailAdmin, "mostcommonwrongpwdever", true}, + {"bad pwd", u.Email, "mostcommonwrongpwdever", true}, {"bad both", "notreal", "mostcommonwrongpwdever", true}, - {"success", cltest.APIEmailAdmin, cltest.Password, false}, + {"success", u.Email, cltest.Password, false}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -370,8 +375,6 @@ func TestSetupSolanaRelayer(t *testing.T) { rf := chainlink.RelayerFactory{ Logger: lggr, - DB: pgtest.NewSqlxDB(t), - QConfig: tConfig.Database(), LoopRegistry: reg, } @@ -457,8 +460,6 @@ func TestSetupStarkNetRelayer(t *testing.T) { }) rf := chainlink.RelayerFactory{ Logger: lggr, - DB: pgtest.NewSqlxDB(t), - QConfig: tConfig.Database(), LoopRegistry: reg, } diff --git a/core/config/env/env.go b/core/config/env/env.go index 7813df4a8c..ea84a50b75 100644 --- a/core/config/env/env.go +++ b/core/config/env/env.go @@ -36,6 +36,8 @@ var ( PyroscopeAuthToken = Secret("CL_PYROSCOPE_AUTH_TOKEN") PrometheusAuthToken = Secret("CL_PROMETHEUS_AUTH_TOKEN") ThresholdKeyShare = Secret("CL_THRESHOLD_KEY_SHARE") + // Migrations env vars + EVMChainIDNotNullMigration0195 = "CL_EVM_CHAINID_NOT_NULL_MIGRATION_0195" ) type Var string diff --git a/core/gethwrappers/OffchainAggregator/OffchainAggregator.abi b/core/gethwrappers/OffchainAggregator/OffchainAggregator.abi index e33ed2b8f3..d83251ac18 100644 --- a/core/gethwrappers/OffchainAggregator/OffchainAggregator.abi +++ b/core/gethwrappers/OffchainAggregator/OffchainAggregator.abi @@ -1 +1 @@ -[{"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"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"address","name":"_validator","type":"address"},{"internalType":"int192","name":"_minAnswer","type":"int192"},{"internalType":"int192","name":"_maxAnswer","type":"int192"},{"internalType":"contract AccessControllerInterface","name":"_billingAccessController","type":"address"},{"internalType":"contract AccessControllerInterface","name":"_requesterAccessController","type":"address"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"string","name":"_description","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"contract AccessControllerInterface","name":"old","type":"address"},{"indexed":false,"internalType":"contract AccessControllerInterface","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":"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":false,"internalType":"address","name":"transmitter","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"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":"contract AccessControllerInterface","name":"old","type":"address"},{"indexed":false,"internalType":"contract AccessControllerInterface","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":"previous","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"}],"name":"ValidatorUpdated","type":"event"},{"inputs":[],"name":"LINK","outputs":[{"internalType":"contract LinkTokenInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"billingAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBilling","outputs":[{"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"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes16","name":"configDigest","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTransmissionDetails","outputs":[{"internalType":"bytes16","name":"configDigest","type":"bytes16"},{"internalType":"uint32","name":"epoch","type":"uint32"},{"internalType":"uint8","name":"round","type":"uint8"},{"internalType":"int192","name":"latestAnswer","type":"int192"},{"internalType":"uint64","name":"latestTimestamp","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkAvailableForPayment","outputs":[{"internalType":"int256","name":"availableBalance","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAnswer","outputs":[{"internalType":"int192","name":"","type":"int192"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAnswer","outputs":[{"internalType":"int192","name":"","type":"int192"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_signerOrTransmitter","type":"address"}],"name":"oracleObservationCount","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"owedPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestNewRound","outputs":[{"internalType":"uint80","name":"","type":"uint80"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requesterAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","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":"setBilling","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AccessControllerInterface","name":"_billingAccessController","type":"address"}],"name":"setBillingAccessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_signers","type":"address[]"},{"internalType":"address[]","name":"_transmitters","type":"address[]"},{"internalType":"uint8","name":"_threshold","type":"uint8"},{"internalType":"uint64","name":"_encodedConfigVersion","type":"uint64"},{"internalType":"bytes","name":"_encoded","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_transmitters","type":"address[]"},{"internalType":"address[]","name":"_payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AccessControllerInterface","name":"_requesterAccessController","type":"address"}],"name":"setRequesterAccessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newValidator","type":"address"}],"name":"setValidator","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":"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":"validator","outputs":[{"internalType":"contract AggregatorValidatorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] \ No newline at end of file +[{"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"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"address","name":"_validator","type":"address"},{"internalType":"int192","name":"_minAnswer","type":"int192"},{"internalType":"int192","name":"_maxAnswer","type":"int192"},{"internalType":"contract AccessControllerInterface","name":"_billingAccessController","type":"address"},{"internalType":"contract AccessControllerInterface","name":"_requesterAccessController","type":"address"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"string","name":"_description","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"contract AccessControllerInterface","name":"old","type":"address"},{"indexed":false,"internalType":"contract AccessControllerInterface","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":"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":false,"internalType":"address","name":"transmitter","type":"address"},{"indexed":false,"internalType":"address","name":"payee","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"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":"contract AccessControllerInterface","name":"old","type":"address"},{"indexed":false,"internalType":"contract AccessControllerInterface","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":"previous","type":"address"},{"indexed":true,"internalType":"address","name":"current","type":"address"}],"name":"ValidatorUpdated","type":"event"},{"inputs":[],"name":"LINK","outputs":[{"internalType":"contract LinkTokenInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"acceptPayeeship","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"billingAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBilling","outputs":[{"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"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint80","name":"_roundId","type":"uint80"}],"name":"getRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_roundId","type":"uint256"}],"name":"getTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestConfigDetails","outputs":[{"internalType":"uint32","name":"configCount","type":"uint32"},{"internalType":"uint32","name":"blockNumber","type":"uint32"},{"internalType":"bytes16","name":"configDigest","type":"bytes16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRound","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"answer","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestTransmissionDetails","outputs":[{"internalType":"bytes16","name":"configDigest","type":"bytes16"},{"internalType":"uint32","name":"epoch","type":"uint32"},{"internalType":"uint8","name":"round","type":"uint8"},{"internalType":"int192","name":"latestAnswer","type":"int192"},{"internalType":"uint64","name":"latestTimestamp","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"linkAvailableForPayment","outputs":[{"internalType":"int256","name":"availableBalance","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAnswer","outputs":[{"internalType":"int192","name":"","type":"int192"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minAnswer","outputs":[{"internalType":"int192","name":"","type":"int192"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_signerOrTransmitter","type":"address"}],"name":"oracleObservationCount","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"owedPayment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestNewRound","outputs":[{"internalType":"uint80","name":"","type":"uint80"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requesterAccessController","outputs":[{"internalType":"contract AccessControllerInterface","name":"","type":"address"}],"stateMutability":"view","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":"setBilling","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AccessControllerInterface","name":"_billingAccessController","type":"address"}],"name":"setBillingAccessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_signers","type":"address[]"},{"internalType":"address[]","name":"_transmitters","type":"address[]"},{"internalType":"uint8","name":"_threshold","type":"uint8"},{"internalType":"uint64","name":"_encodedConfigVersion","type":"uint64"},{"internalType":"bytes","name":"_encoded","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_transmitters","type":"address[]"},{"internalType":"address[]","name":"_payees","type":"address[]"}],"name":"setPayees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract AccessControllerInterface","name":"_requesterAccessController","type":"address"}],"name":"setRequesterAccessController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newValidator","type":"address"}],"name":"setValidator","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":"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":"validator","outputs":[{"internalType":"contract AggregatorValidatorInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_transmitter","type":"address"}],"name":"withdrawPayment","outputs":[],"stateMutability":"nonpayable","type":"function"}] diff --git a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go index f7d7a7bf3e..9ebcd2d332 100644 --- a/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go +++ b/core/gethwrappers/ccip/generated/burn_mint_token_pool/burn_mint_token_pool.go @@ -51,8 +51,8 @@ type TokenPoolRampUpdate struct { } var BurnMintTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"NonExistentRamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermissionsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"RampAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"onRamps\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"offRamps\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"currentOffRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"currentOnRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOnRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"isOnRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOffRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOnRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60e06040523480156200001157600080fd5b5060405162002edc38038062002edc83398101604081905262000034916200051d565b82828233806000816200008e5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c157620000c18162000133565b5050506001600160a01b038316620000ec576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808416608052811660a052815115801560c0526200012757604080516000815260208101909152620001279083620001de565b5050505050506200068e565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000085565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620001ff576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002945760008382815181106200022357620002236200061a565b602090810291909101015190506200023d6002826200034f565b1562000280576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506200028c8162000646565b905062000202565b5060005b81518110156200034a576000828281518110620002b957620002b96200061a565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002e5575062000337565b620002f26002826200036f565b1562000335576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b620003428162000646565b905062000298565b505050565b600062000366836001600160a01b03841662000386565b90505b92915050565b600062000366836001600160a01b0384166200048a565b600081815260018301602052604081205480156200047f576000620003ad60018362000662565b8554909150600090620003c39060019062000662565b90508181146200042f576000866000018281548110620003e757620003e76200061a565b90600052602060002001549050808760000184815481106200040d576200040d6200061a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000443576200044362000678565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000369565b600091505062000369565b6000818152600183016020526040812054620004d35750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000369565b50600062000369565b6001600160a01b0381168114620004f257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200051881620004dc565b919050565b6000806000606084860312156200053357600080fd5b83516200054081620004dc565b602085810151919450906001600160401b03808211156200056057600080fd5b818701915087601f8301126200057557600080fd5b8151818111156200058a576200058a620004f5565b8060051b604051601f19603f83011681018181108582111715620005b257620005b2620004f5565b60405291825284820192508381018501918a831115620005d157600080fd5b938501935b82851015620005fa57620005ea856200050b565b84529385019392850192620005d6565b80975050505050505062000611604085016200050b565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200065b576200065b62000630565b5060010190565b8181038181111562000369576200036962000630565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c0516127e6620006f66000396000818161037c015281816109eb0152610ec10152600081816101f50152818161078e0152610a6f0152600081816101ae015281816108e601528181610b6b01528181611301015261134801526127e66000f3fe608060405234801561001057600080fd5b506004361061016c5760003560e01c806387381314116100cd578063b3a3fb4111610081578063d612b94511610066578063d612b94514610367578063e0351e131461037a578063f2fde38b146103a057600080fd5b8063b3a3fb4114610341578063c49907b51461035457600080fd5b806396875445116100b25780639687544514610311578063a40e69c714610331578063a7cd63b71461033957600080fd5b806387381314146102de5780638da5cb5b146102f357600080fd5b80636f32b872116101245780637787e7ab116101095780637787e7ab1461025457806379ba5097146102c35780638627fad6146102cb57600080fd5b80636f32b8721461022e5780637448b3c71461024157600080fd5b806321df0da71161015557806321df0da7146101ac5780635246492f146101f357806354c8a4f31461021957600080fd5b806301ffc9a7146101715780631d7a74a014610199575b600080fd5b61018461017f366004611fb4565b6103b3565b60405190151581526020015b60405180910390f35b6101846101a736600461201f565b61044c565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610190565b7f00000000000000000000000000000000000000000000000000000000000000006101ce565b61022c610227366004612086565b610459565b005b61018461023c36600461201f565b6104d4565b61022c61024f3660046121c9565b6104e1565b61026761026236600461201f565b6105b1565b604051610190919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b61022c61068f565b61022c6102d93660046122c0565b61078c565b6102e6610996565b604051610190919061234f565b60005473ffffffffffffffffffffffffffffffffffffffff166101ce565b61032461031f3660046123eb565b6109a7565b6040516101909190612489565b6102e6610c2d565b6102e6610c39565b61026761034f36600461201f565b610c45565b61022c61036236600461253a565b610d23565b61022c6103753660046121c9565b610d37565b7f0000000000000000000000000000000000000000000000000000000000000000610184565b61022c6103ae36600461201f565b610df6565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa33400000000000000000000000000000000000000000000000000000000148061044657507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b6000610446600783610e0a565b610461610e3c565b6104ce84848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250610ebf92505050565b50505050565b6000610446600483610e0a565b6104e9610e3c565b6104f2826104d4565b610545576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166000908152600660205260409020610574908261108a565b7f578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed682826040516105a592919061259a565b60405180910390a15050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260066020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261044690611239565b60015473ffffffffffffffffffffffffffffffffffffffff163314610710576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161053c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081b91906125f2565b15610852576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61085b3361044c565b610891576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61089a836112eb565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561092a57600080fd5b505af115801561093e573d6000803e3d6000fd5b505060405185815273ffffffffffffffffffffffffffffffffffffffff871692503391507f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f09060200160405180910390a35050505050565b60606109a26004611325565b905090565b60606109b2336104d4565b6109e8576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b877f00000000000000000000000000000000000000000000000000000000000000008015610a1e5750610a1c600282610e0a565b155b15610a6d576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015260240161053c565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ad8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610afc91906125f2565b15610b33576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b3c86611332565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018790527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610bc457600080fd5b505af1158015610bd8573d6000803e3d6000fd5b50506040518881523392507f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7915060200160405180910390a25050604080516020810190915260008152979650505050505050565b60606109a26007611325565b60606109a26002611325565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260096020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261044690611239565b610d2b610e3c565b6104ce8484848461136c565b610d3f610e3c565b610d488261044c565b610d96576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8316600482015260240161053c565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600960205260409020610dc5908261108a565b7fb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f82826040516105a592919061259a565b610dfe610e3c565b610e078161191c565b50565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ebd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161053c565b565b7f0000000000000000000000000000000000000000000000000000000000000000610f16576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015610fb4576000838281518110610f3657610f3661260f565b60200260200101519050610f54816002611a1190919063ffffffff16565b15610fa35760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50610fad8161266d565b9050610f19565b5060005b8151811015611085576000828281518110610fd557610fd561260f565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036110195750611075565b611024600282611a33565b156110735760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b61107e8161266d565b9050610fb8565b505050565b81546000906110b390700100000000000000000000000000000000900463ffffffff16426126a5565b9050801561115557600183015483546110fb916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416611a55565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461117b916fffffffffffffffffffffffffffffffff9081169116611a7d565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061122c9084906126b8565b60405180910390a1505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526112c782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426112ab91906126a5565b85608001516fffffffffffffffffffffffffffffffff16611a55565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b336000908152600960205260409020610e0790827f0000000000000000000000000000000000000000000000000000000000000000611a93565b60606000610e3583611e16565b336000908152600660205260409020610e0790827f0000000000000000000000000000000000000000000000000000000000000000611a93565b611374610e3c565b60005b838110156116915760008585838181106113935761139361260f565b905060a002018036038101906113a991906126f4565b90508060200151156115815780516113c390600490611a33565b15611534576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526006909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac92611527929161259a565b60405180910390a1611680565b80516040517fd3eb6bc500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161053c565b805161158f90600490611a11565b1561163357805173ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517f7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b5294916115279173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b80516040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161053c565b5061168a8161266d565b9050611377565b5060005b818110156119155760008383838181106116b1576116b161260f565b905060a002018036038101906116c791906126f4565b90508060200151156118525780516116e190600790611a33565b15611534576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526009909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d8892611845929161259a565b60405180910390a1611904565b805161186090600790611a11565b1561163357805173ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517fcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c916118459173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b5061190e8161266d565b9050611695565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff82160361199b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161053c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000610e358373ffffffffffffffffffffffffffffffffffffffff8416611e72565b6000610e358373ffffffffffffffffffffffffffffffffffffffff8416611f65565b6000611a7485611a658486612745565b611a6f908761275c565b611a7d565b95945050505050565b6000818310611a8c5781610e35565b5090919050565b825474010000000000000000000000000000000000000000900460ff161580611aba575081155b15611ac457505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090611b0a90700100000000000000000000000000000000900463ffffffff16426126a5565b90508015611bca5781831115611b4c576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154611b869083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16611a55565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015611c815773ffffffffffffffffffffffffffffffffffffffff8416611c29576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161053c565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161053c565b84831015611d945760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290611cc590826126a5565b611ccf878a6126a5565b611cd9919061275c565b611ce3919061276f565b905073ffffffffffffffffffffffffffffffffffffffff8616611d3c576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161053c565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161053c565b611d9e85846126a5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611e6657602002820191906000526020600020905b815481526020019060010190808311611e52575b50505050509050919050565b60008181526001830160205260408120548015611f5b576000611e966001836126a5565b8554909150600090611eaa906001906126a5565b9050818114611f0f576000866000018281548110611eca57611eca61260f565b9060005260206000200154905080876000018481548110611eed57611eed61260f565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611f2057611f206127aa565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610446565b6000915050610446565b6000818152600183016020526040812054611fac57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610446565b506000610446565b600060208284031215611fc657600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e3557600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461201a57600080fd5b919050565b60006020828403121561203157600080fd5b610e3582611ff6565b60008083601f84011261204c57600080fd5b50813567ffffffffffffffff81111561206457600080fd5b6020830191508360208260051b850101111561207f57600080fd5b9250929050565b6000806000806040858703121561209c57600080fd5b843567ffffffffffffffff808211156120b457600080fd5b6120c08883890161203a565b909650945060208701359150808211156120d957600080fd5b506120e68782880161203a565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612144576121446120f2565b60405290565b8015158114610e0757600080fd5b80356fffffffffffffffffffffffffffffffff8116811461201a57600080fd5b60006060828403121561218a57600080fd5b612192612121565b9050813561219f8161214a565b81526121ad60208301612158565b60208201526121be60408301612158565b604082015292915050565b600080608083850312156121dc57600080fd5b6121e583611ff6565b91506121f48460208501612178565b90509250929050565b600082601f83011261220e57600080fd5b813567ffffffffffffffff80821115612229576122296120f2565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561226f5761226f6120f2565b8160405283815286602085880101111561228857600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff8116811461201a57600080fd5b600080600080600060a086880312156122d857600080fd5b853567ffffffffffffffff808211156122f057600080fd5b6122fc89838a016121fd565b965061230a60208901611ff6565b95506040880135945061231f606089016122a8565b9350608088013591508082111561233557600080fd5b50612342888289016121fd565b9150509295509295909350565b6020808252825182820181905260009190848201906040850190845b8181101561239d57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161236b565b50909695505050505050565b60008083601f8401126123bb57600080fd5b50813567ffffffffffffffff8111156123d357600080fd5b60208301915083602082850101111561207f57600080fd5b600080600080600080600060a0888a03121561240657600080fd5b61240f88611ff6565b9650602088013567ffffffffffffffff8082111561242c57600080fd5b6124388b838c016123a9565b909850965060408a0135955086915061245360608b016122a8565b945060808a013591508082111561246957600080fd5b506124768a828b016123a9565b989b979a50959850939692959293505050565b600060208083528351808285015260005b818110156124b65785810183015185820160400152820161249a565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60008083601f84011261250757600080fd5b50813567ffffffffffffffff81111561251f57600080fd5b60208301915083602060a08302850101111561207f57600080fd5b6000806000806040858703121561255057600080fd5b843567ffffffffffffffff8082111561256857600080fd5b612574888389016124f5565b9096509450602087013591508082111561258d57600080fd5b506120e6878288016124f5565b73ffffffffffffffffffffffffffffffffffffffff8316815260808101610e3560208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561260457600080fd5b8151610e358161214a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361269e5761269e61263e565b5060010190565b818103818111156104465761044661263e565b6060810161044682848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060a0828403121561270657600080fd5b61270e612121565b61271783611ff6565b815260208301356127278161214a565b60208201526127398460408501612178565b60408201529392505050565b80820281158282048414176104465761044661263e565b808201808211156104465761044661263e565b6000826127a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"NonExistentRamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermissionsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"RampAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"onRamps\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"offRamps\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"currentOffRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"currentOnRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOnRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"isOnRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOffRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOnRampRateLimiterConfig\",\"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\":\"view\",\"type\":\"function\"}]", + Bin: "0x60e06040523480156200001157600080fd5b5060405162002f2e38038062002f2e83398101604081905262000034916200051d565b82828233806000816200008e5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c157620000c18162000133565b5050506001600160a01b038316620000ec576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808416608052811660a052815115801560c0526200012757604080516000815260208101909152620001279083620001de565b5050505050506200068e565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000085565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c051620001ff576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002945760008382815181106200022357620002236200061a565b602090810291909101015190506200023d6002826200034f565b1562000280576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506200028c8162000646565b905062000202565b5060005b81518110156200034a576000828281518110620002b957620002b96200061a565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002e5575062000337565b620002f26002826200036f565b1562000335576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b620003428162000646565b905062000298565b505050565b600062000366836001600160a01b03841662000386565b90505b92915050565b600062000366836001600160a01b0384166200048a565b600081815260018301602052604081205480156200047f576000620003ad60018362000662565b8554909150600090620003c39060019062000662565b90508181146200042f576000866000018281548110620003e757620003e76200061a565b90600052602060002001549050808760000184815481106200040d576200040d6200061a565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000443576200044362000678565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000369565b600091505062000369565b6000818152600183016020526040812054620004d35750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000369565b50600062000369565b6001600160a01b0381168114620004f257600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200051881620004dc565b919050565b6000806000606084860312156200053357600080fd5b83516200054081620004dc565b602085810151919450906001600160401b03808211156200056057600080fd5b818701915087601f8301126200057557600080fd5b8151818111156200058a576200058a620004f5565b8060051b604051601f19603f83011681018181108582111715620005b257620005b2620004f5565b60405291825284820192508381018501918a831115620005d157600080fd5b938501935b82851015620005fa57620005ea856200050b565b84529385019392850192620005d6565b80975050505050505062000611604085016200050b565b90509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200065b576200065b62000630565b5060010190565b8181038181111562000369576200036962000630565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c051612838620006f6600039600081816103c301528181610a320152610f08015260008181610249015281816107d50152610ab60152600081816102020152818161092d01528181610bb201528181611348015261138f01526128386000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c80638627fad6116100d8578063a7cd63b71161008c578063d612b94511610066578063d612b945146103ae578063e0351e13146103c1578063f2fde38b146103e757600080fd5b8063a7cd63b714610380578063b3a3fb4114610388578063c49907b51461039b57600080fd5b80638da5cb5b116100bd5780638da5cb5b146103475780639687544514610365578063a40e69c71461037857600080fd5b80638627fad61461031f578063873813141461033257600080fd5b806354c8a4f31161012f5780637448b3c7116101145780637448b3c7146102955780637787e7ab146102a857806379ba50971461031757600080fd5b806354c8a4f31461026d5780636f32b8721461028257600080fd5b80631d7a74a0116101605780631d7a74a0146101ed57806321df0da7146102005780635246492f1461024757600080fd5b806301ffc9a71461017c578063181f5a77146101a4575b600080fd5b61018f61018a366004611ffb565b6103fa565b60405190151581526020015b60405180910390f35b6101e06040518060400160405280601781526020017f4275726e4d696e74546f6b656e506f6f6c20312e322e3000000000000000000081525081565b60405161019b91906120a1565b61018f6101fb3660046120dd565b610493565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019b565b7f0000000000000000000000000000000000000000000000000000000000000000610222565b61028061027b366004612144565b6104a0565b005b61018f6102903660046120dd565b61051b565b6102806102a3366004612287565b610528565b6102bb6102b63660046120dd565b6105f8565b60405161019b919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6102806106d6565b61028061032d36600461237e565b6107d3565b61033a6109dd565b60405161019b919061240d565b60005473ffffffffffffffffffffffffffffffffffffffff16610222565b6101e06103733660046124a9565b6109ee565b61033a610c74565b61033a610c80565b6102bb6103963660046120dd565b610c8c565b6102806103a936600461258c565b610d6a565b6102806103bc366004612287565b610d7e565b7f000000000000000000000000000000000000000000000000000000000000000061018f565b6102806103f53660046120dd565b610e3d565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa33400000000000000000000000000000000000000000000000000000000148061048d57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b600061048d600783610e51565b6104a8610e83565b61051584848080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808802828101820190935287825290935087925086918291850190849080828437600092019190915250610f0692505050565b50505050565b600061048d600483610e51565b610530610e83565b6105398261051b565b61058c576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526006602052604090206105bb90826110d1565b7f578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed682826040516105ec9291906125ec565b60405180910390a15050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260066020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261048d90611280565b60015473ffffffffffffffffffffffffffffffffffffffff163314610757576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610583565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561083e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108629190612644565b15610899576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108a233610493565b6108d8576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108e183611332565b6040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018590527f000000000000000000000000000000000000000000000000000000000000000016906340c10f1990604401600060405180830381600087803b15801561097157600080fd5b505af1158015610985573d6000803e3d6000fd5b505060405185815273ffffffffffffffffffffffffffffffffffffffff871692503391507f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f09060200160405180910390a35050505050565b60606109e9600461136c565b905090565b60606109f93361051b565b610a2f576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b877f00000000000000000000000000000000000000000000000000000000000000008015610a655750610a63600282610e51565b155b15610ab4576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610583565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b439190612644565b15610b7a576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b8386611379565b6040517f42966c68000000000000000000000000000000000000000000000000000000008152600481018790527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906342966c6890602401600060405180830381600087803b158015610c0b57600080fd5b505af1158015610c1f573d6000803e3d6000fd5b50506040518881523392507f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df7915060200160405180910390a25050604080516020810190915260008152979650505050505050565b60606109e9600761136c565b60606109e9600261136c565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260096020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261048d90611280565b610d72610e83565b610515848484846113b3565b610d86610e83565b610d8f82610493565b610ddd576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610583565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600960205260409020610e0c90826110d1565b7fb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f82826040516105ec9291906125ec565b610e45610e83565b610e4e81611963565b50565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610f04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610583565b565b7f0000000000000000000000000000000000000000000000000000000000000000610f5d576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8251811015610ffb576000838281518110610f7d57610f7d612661565b60200260200101519050610f9b816002611a5890919063ffffffff16565b15610fea5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50610ff4816126bf565b9050610f60565b5060005b81518110156110cc57600082828151811061101c5761101c612661565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361106057506110bc565b61106b600282611a7a565b156110ba5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6110c5816126bf565b9050610fff565b505050565b81546000906110fa90700100000000000000000000000000000000900463ffffffff16426126f7565b9050801561119c5760018301548354611142916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416611a9c565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546111c2916fffffffffffffffffffffffffffffffff9081169116611ac4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061127390849061270a565b60405180910390a1505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261130e82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426112f291906126f7565b85608001516fffffffffffffffffffffffffffffffff16611a9c565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b336000908152600960205260409020610e4e90827f0000000000000000000000000000000000000000000000000000000000000000611ada565b60606000610e7c83611e5d565b336000908152600660205260409020610e4e90827f0000000000000000000000000000000000000000000000000000000000000000611ada565b6113bb610e83565b60005b838110156116d85760008585838181106113da576113da612661565b905060a002018036038101906113f09190612746565b90508060200151156115c857805161140a90600490611a7a565b1561157b576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526006909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac9261156e92916125ec565b60405180910390a16116c7565b80516040517fd3eb6bc500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610583565b80516115d690600490611a58565b1561167a57805173ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517f7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b52949161156e9173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b80516040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610583565b506116d1816126bf565b90506113be565b5060005b8181101561195c5760008383838181106116f8576116f8612661565b905060a0020180360381019061170e9190612746565b905080602001511561189957805161172890600790611a7a565b1561157b576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526009909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d889261188c92916125ec565b60405180910390a161194b565b80516118a790600790611a58565b1561167a57805173ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517fcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c9161188c9173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b50611955816126bf565b90506116dc565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036119e2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610583565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000610e7c8373ffffffffffffffffffffffffffffffffffffffff8416611eb9565b6000610e7c8373ffffffffffffffffffffffffffffffffffffffff8416611fac565b6000611abb85611aac8486612797565b611ab690876127ae565b611ac4565b95945050505050565b6000818310611ad35781610e7c565b5090919050565b825474010000000000000000000000000000000000000000900460ff161580611b01575081155b15611b0b57505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090611b5190700100000000000000000000000000000000900463ffffffff16426126f7565b90508015611c115781831115611b93576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001860154611bcd9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16611a9c565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015611cc85773ffffffffffffffffffffffffffffffffffffffff8416611c70576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610583565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610583565b84831015611ddb5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290611d0c90826126f7565b611d16878a6126f7565b611d2091906127ae565b611d2a91906127c1565b905073ffffffffffffffffffffffffffffffffffffffff8616611d83576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610583565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610583565b611de585846126f7565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611ead57602002820191906000526020600020905b815481526020019060010190808311611e99575b50505050509050919050565b60008181526001830160205260408120548015611fa2576000611edd6001836126f7565b8554909150600090611ef1906001906126f7565b9050818114611f56576000866000018281548110611f1157611f11612661565b9060005260206000200154905080876000018481548110611f3457611f34612661565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080611f6757611f676127fc565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061048d565b600091505061048d565b6000818152600183016020526040812054611ff35750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561048d565b50600061048d565b60006020828403121561200d57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610e7c57600080fd5b6000815180845260005b8181101561206357602081850181015186830182015201612047565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081526000610e7c602083018461203d565b803573ffffffffffffffffffffffffffffffffffffffff811681146120d857600080fd5b919050565b6000602082840312156120ef57600080fd5b610e7c826120b4565b60008083601f84011261210a57600080fd5b50813567ffffffffffffffff81111561212257600080fd5b6020830191508360208260051b850101111561213d57600080fd5b9250929050565b6000806000806040858703121561215a57600080fd5b843567ffffffffffffffff8082111561217257600080fd5b61217e888389016120f8565b9096509450602087013591508082111561219757600080fd5b506121a4878288016120f8565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612202576122026121b0565b60405290565b8015158114610e4e57600080fd5b80356fffffffffffffffffffffffffffffffff811681146120d857600080fd5b60006060828403121561224857600080fd5b6122506121df565b9050813561225d81612208565b815261226b60208301612216565b602082015261227c60408301612216565b604082015292915050565b6000806080838503121561229a57600080fd5b6122a3836120b4565b91506122b28460208501612236565b90509250929050565b600082601f8301126122cc57600080fd5b813567ffffffffffffffff808211156122e7576122e76121b0565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561232d5761232d6121b0565b8160405283815286602085880101111561234657600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff811681146120d857600080fd5b600080600080600060a0868803121561239657600080fd5b853567ffffffffffffffff808211156123ae57600080fd5b6123ba89838a016122bb565b96506123c8602089016120b4565b9550604088013594506123dd60608901612366565b935060808801359150808211156123f357600080fd5b50612400888289016122bb565b9150509295509295909350565b6020808252825182820181905260009190848201906040850190845b8181101561245b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612429565b50909695505050505050565b60008083601f84011261247957600080fd5b50813567ffffffffffffffff81111561249157600080fd5b60208301915083602082850101111561213d57600080fd5b600080600080600080600060a0888a0312156124c457600080fd5b6124cd886120b4565b9650602088013567ffffffffffffffff808211156124ea57600080fd5b6124f68b838c01612467565b909850965060408a0135955086915061251160608b01612366565b945060808a013591508082111561252757600080fd5b506125348a828b01612467565b989b979a50959850939692959293505050565b60008083601f84011261255957600080fd5b50813567ffffffffffffffff81111561257157600080fd5b60208301915083602060a08302850101111561213d57600080fd5b600080600080604085870312156125a257600080fd5b843567ffffffffffffffff808211156125ba57600080fd5b6125c688838901612547565b909650945060208701359150808211156125df57600080fd5b506121a487828801612547565b73ffffffffffffffffffffffffffffffffffffffff8316815260808101610e7c60208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b60006020828403121561265657600080fd5b8151610e7c81612208565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036126f0576126f0612690565b5060010190565b8181038181111561048d5761048d612690565b6060810161048d82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060a0828403121561275857600080fd5b6127606121df565b612769836120b4565b8152602083013561277981612208565b602082015261278b8460408501612236565b60408201529392505050565b808202811582820484141761048d5761048d612690565b8082018082111561048d5761048d612690565b6000826127f7577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var BurnMintTokenPoolABI = BurnMintTokenPoolMetaData.ABI @@ -455,6 +455,28 @@ func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) SupportsInterface(inte return _BurnMintTokenPool.Contract.SupportsInterface(&_BurnMintTokenPool.CallOpts, interfaceId) } +func (_BurnMintTokenPool *BurnMintTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _BurnMintTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_BurnMintTokenPool *BurnMintTokenPoolSession) TypeAndVersion() (string, error) { + return _BurnMintTokenPool.Contract.TypeAndVersion(&_BurnMintTokenPool.CallOpts) +} + +func (_BurnMintTokenPool *BurnMintTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _BurnMintTokenPool.Contract.TypeAndVersion(&_BurnMintTokenPool.CallOpts) +} + func (_BurnMintTokenPool *BurnMintTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { return _BurnMintTokenPool.contract.Transact(opts, "acceptOwnership") } @@ -2414,6 +2436,8 @@ type BurnMintTokenPoolInterface interface { SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + TypeAndVersion(opts *bind.CallOpts) (string, error) + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/commit_store/commit_store.go b/core/gethwrappers/ccip/generated/commit_store/commit_store.go index c9518b70e7..288e82954a 100644 --- a/core/gethwrappers/ccip/generated/commit_store/commit_store.go +++ b/core/gethwrappers/ccip/generated/commit_store/commit_store.go @@ -52,20 +52,24 @@ type CommitStoreStaticConfig struct { ArmProxy common.Address } -type InternalPriceUpdates struct { - TokenPriceUpdates []InternalTokenPriceUpdate +type InternalGasPriceUpdate struct { DestChainSelector uint64 UsdPerUnitGas *big.Int } +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + type InternalTokenPriceUpdate struct { SourceToken common.Address UsdPerToken *big.Int } var CommitStoreMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":\"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\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"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\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b5060405162003794380380620037948339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516133ff620003956000396000818161026d01528181610537015281816111730152818161199f01528181611bee015261206b0152600081816102310152611bc70152600081816102010152611ba00152600081816101d10152611b710152600081816112ee015261133a015260006113b501526133ff6000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063ad7a22f81161008c578063f2fde38b11610066578063f2fde38b146104fa578063f47a86901461050d578063ff888fb11461052057600080fd5b8063ad7a22f8146104b4578063afcb95d7146104c7578063b1dc65a4146104e757600080fd5b80638da5cb5b116100bd5780638da5cb5b146104645780638db94e441461048c578063a7206cd61461049457600080fd5b806379ba50971461042457806381ff70481461042c5780638456cb591461045c57600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103b4578063666cab8d146103d05780637437ff9f146103e557600080fd5b806332048875146103795780633f4ba83a1461039a5780634120fccd146103a257600080fd5b8063181f5a7711610176578063181f5a77146103085780631ef381741461035157806329b980e41461036657600080fd5b806306285c691461019d5780630a6cd30d146102c057806310c374ed146102d8575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b7919061265f565b60405180910390f35b6102c8610533565b60405190151581526020016102b7565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b6103446040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102b7919061271c565b61036461035f36600461296f565b6105ca565b005b610364610374366004612a3c565b610deb565b61038c610387366004612aaf565b610e37565b6040519081526020016102b7565b610364610f2d565b60095467ffffffffffffffff166102ef565b6009546d0100000000000000000000000000900460ff166102c8565b6103d8610f93565b6040516102b79190612b74565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b610364611002565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b6103646110ff565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6102c861116f565b61038c6104a2366004612b87565b6000908152600a602052604090205490565b6103646104c2366004612ba0565b611226565b6040805160018152600060208201819052918101919091526060016102b7565b6103646104f5366004612bbb565b611269565b610364610508366004612ca0565b611889565b61036461051b366004612cbd565b61189d565b6102c861052e366004612b87565b61193c565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612cff565b15905090565b855185518560ff16601f831115610642576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106ac576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610639565b81831461073a576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610639565b610745816003612d50565b83116107ad576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610639565b6107b5611a10565b6107be86611a93565b60065460005b818110156108ba5760056000600683815481106107e3576107e3612d67565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061085357610853612d67565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108b381612d96565b90506107c4565b50895160005b81811015610c935760008c82815181106108dc576108dc612d67565b60200260200101519050600060028111156108f9576108f9612dce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561093857610938612dce565b1461099f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff81166109ec576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9c57610a9c612dce565b021790555090505060008c8381518110610ab857610ab8612d67565b6020026020010151905060006002811115610ad557610ad5612dce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b1457610b14612dce565b14610b7b576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff8116610bc8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c7857610c78612dce565b0217905550905050505080610c8c90612d96565b90506108c0565b508a51610ca79060069060208e01906125a1565b508951610cbb9060079060208d01906125a1565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d41914691309190600090610d139063ffffffff16612dfd565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611c4f565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610dd599989796959493929190612e20565b60405180910390a1505050505050505050505050565b610df3611a10565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610e88576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ef987878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611cfa915050565b9050610f048161193c565b610f12576000915050610f24565b6000908152600a602052604090205490505b95945050505050565b610f35611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610ff857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610fcd575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610639565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611107611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610f89565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190612cff565b15801561122157506009546d0100000000000000000000000000900460ff16155b905090565b61122e611a10565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b611278878760208b013561201b565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146112eb5780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610639565b467f00000000000000000000000000000000000000000000000000000000000000001461136c576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610639565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561140e576002826020015183604001516113ef9190612eb6565b6113f99190612ecf565b611404906001612eb6565b60ff169050611424565b602082015161141e906001612eb6565b60ff1690505b86811461145d576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611496576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156114d9576114d9612dce565b60028111156114ea576114ea612dce565b905250905060028160200151600281111561150757611507612dce565b14801561154e57506007816000015160ff168154811061152957611529612d67565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611584576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611592866020612d50565b61159d896020612d50565b6115a98c610144612f18565b6115b39190612f18565b6115bd9190612f18565b9050368114611601576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610639565b5060008a8a604051611614929190612f2b565b60405190819003812061162b918e90602001612f3b565b60405160208183030381529060405280519060200120905061164b61262b565b8860005b818110156118785760006001858a846020811061166e5761166e612d67565b61167b91901a601b612eb6565b8f8f8681811061168d5761168d612d67565b905060200201358e8e878181106116a6576116a6612d67565b90506020020135604051600081526020016040526040516116e3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611705573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561178857611788612dce565b600281111561179957611799612dce565b90525090506001816020015160028111156117b6576117b6612dce565b146117ed576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061180457611804612d67565b602002015115611840576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061185b5761185b612d67565b9115156020909202015250611871905081612d96565b905061164f565b505050505050505050505050505050565b611891611a10565b61189a81612431565b50565b6118a5611a10565b60005b818110156119375760008383838181106118c4576118c4612d67565b9050602002013590506118d68161193c565b611926576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061191d9083815260200190565b60405180910390a15b5061193081612d96565b90506118a8565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156119e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0a9190612cff565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610639565b565b600081806020019051810190611aa99190612f4f565b805190915073ffffffffffffffffffffffffffffffffffffffff16611afa576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391611c43918490612f9b565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611c7399989796959493929190613018565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611d3b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611d4f57506101018111155b611d85576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611de6576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611e135786600081518110611e0157611e01612d67565b60200260200101519350505050612014565b60008167ffffffffffffffff811115611e2e57611e2e61272f565b604051908082528060200260200182016040528015611e57578160200160208202803683370190505b50905060008080805b85811015611f9a5760006001821b8b811603611ebb5788851015611ea4578c5160018601958e918110611e9557611e95612d67565b60200260200101519050611edd565b8551600185019487918110611e9557611e95612d67565b8b5160018401938d918110611ed257611ed2612d67565b602002602001015190505b600089861015611f0d578d5160018701968f918110611efe57611efe612d67565b60200260200101519050611f2f565b8651600186019588918110611f2457611f24612d67565b602002602001015190505b82851115611f69576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f738282612526565b878481518110611f8557611f85612d67565b60209081029190910101525050600101611e60565b506001850382148015611fac57508683145b8015611fb757508581145b611fed576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061200257612002612d67565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615612069576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612cff565b1561212f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061213d83850185613117565b8051515190915015158061215f575080516020015167ffffffffffffffff1615155b156122975760095464ffffffffff8084166801000000000000000090920416101561225c57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f98f5be1b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916398f5be1b9161221691600401613336565b600060405180830381600087803b15801561223057600080fd5b505af1158015612244573d6000803e3d6000fd5b5050505060408101516122575750505050565b612297565b6040810151612297576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806122d2575060208082015190810151905167ffffffffffffffff9182169116115b1561230f5780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106399190613349565b604081015161234a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415612393576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015101516123a690600161336e565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517fc14f9167b03b9a5725671c8678a54571219bff700e4a3665aef9e096c6a846f890612423908390613396565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610639565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106125685760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612014565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612014565b82805482825590600052602060002090810192821561261b579160200282015b8281111561261b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125c1565b5061262792915061264a565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115612627576000815560010161264b565b60808101611a0a828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126de576020818501810151868301820152016126c2565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061201460208301846126b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156127815761278161272f565b60405290565b6040516060810167ffffffffffffffff811182821017156127815761278161272f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127f1576127f161272f565b604052919050565b600067ffffffffffffffff8211156128135761281361272f565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461189a57600080fd5b600082601f83011261285057600080fd5b81356020612865612860836127f9565b6127aa565b82815260059290921b8401810191818101908684111561288457600080fd5b8286015b848110156128a857803561289b8161281d565b8352918301918301612888565b509695505050505050565b803560ff811681146128c457600080fd5b919050565b600082601f8301126128da57600080fd5b813567ffffffffffffffff8111156128f4576128f461272f565b61292560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127aa565b81815284602083860101111561293a57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146128c457600080fd5b60008060008060008060c0878903121561298857600080fd5b863567ffffffffffffffff808211156129a057600080fd5b6129ac8a838b0161283f565b975060208901359150808211156129c257600080fd5b6129ce8a838b0161283f565b96506129dc60408a016128b3565b955060608901359150808211156129f257600080fd5b6129fe8a838b016128c9565b9450612a0c60808a01612957565b935060a0890135915080821115612a2257600080fd5b50612a2f89828a016128c9565b9150509295509295509295565b600060208284031215612a4e57600080fd5b813564ffffffffff8116811461201457600080fd5b60008083601f840112612a7557600080fd5b50813567ffffffffffffffff811115612a8d57600080fd5b6020830191508360208260051b8501011115612aa857600080fd5b9250929050565b600080600080600060608688031215612ac757600080fd5b853567ffffffffffffffff80821115612adf57600080fd5b612aeb89838a01612a63565b90975095506020880135915080821115612b0457600080fd5b50612b1188828901612a63565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612b6957815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b37565b509495945050505050565b6020815260006120146020830184612b23565b600060208284031215612b9957600080fd5b5035919050565b600060208284031215612bb257600080fd5b61201482612957565b60008060008060008060008060e0898b031215612bd757600080fd5b606089018a811115612be857600080fd5b8998503567ffffffffffffffff80821115612c0257600080fd5b818b0191508b601f830112612c1657600080fd5b813581811115612c2557600080fd5b8c6020828501011115612c3757600080fd5b6020830199508098505060808b0135915080821115612c5557600080fd5b612c618c838d01612a63565b909750955060a08b0135915080821115612c7a57600080fd5b50612c878b828c01612a63565b999c989b50969995989497949560c00135949350505050565b600060208284031215612cb257600080fd5b81356120148161281d565b60008060208385031215612cd057600080fd5b823567ffffffffffffffff811115612ce757600080fd5b612cf385828601612a63565b90969095509350505050565b600060208284031215612d1157600080fd5b8151801515811461201457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a0a57611a0a612d21565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612dc757612dc7612d21565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612e1657612e16612d21565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612e508184018a612b23565b90508281036080840152612e648189612b23565b905060ff871660a084015282810360c0840152612e8181876126b8565b905067ffffffffffffffff851660e0840152828103610100840152612ea681856126b8565b9c9b505050505050505050505050565b60ff8181168382160190811115611a0a57611a0a612d21565b600060ff831680612f09577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a0a57611a0a612d21565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f6157600080fd5b6040516020810181811067ffffffffffffffff82111715612f8457612f8461272f565b6040528251612f928161281d565b81529392505050565b60a08101612ff4828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b16604085015281606085015261305f8285018b612b23565b91508382036080850152613073828a612b23565b915060ff881660a085015283820360c085015261309082886126b8565b90861660e08501528381036101008501529050612ea681856126b8565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146128c457600080fd5b6000604082840312156130eb57600080fd5b6130f361275e565b90506130fe82612957565b815261310c60208301612957565b602082015292915050565b6000602080838503121561312a57600080fd5b823567ffffffffffffffff8082111561314257600080fd5b908401906080828703121561315657600080fd5b61315e612787565b82358281111561316d57600080fd5b83016060818903121561317f57600080fd5b613187612787565b81358481111561319657600080fd5b82019350601f840189136131a957600080fd5b83356131b7612860826127f9565b81815260069190911b8501870190878101908b8311156131d657600080fd5b958801955b8287101561322a576040878d0312156131f45760008081fd5b6131fc61275e565b87356132078161281d565b8152613214888b016130ad565b818b0152825260409690960195908801906131db565b83525061323a9050828701612957565b8682015261324a604083016130ad565b604082015282525061325e878486016130d9565b93810193909352506060013560408201529392505050565b805160608084528151908401819052600091602091908201906080860190845b818110156132f1578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192604090920191600101613296565b505067ffffffffffffffff83860151168387015260408501519250610f2460408701847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b6020815260006120146020830184613276565b60408101611a0a8284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338f5761338f612d21565b5092915050565b6020815260008251608060208401526133b260a0840182613276565b905060208401516133dd6040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":\"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\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"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\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b506040516200384c3803806200384c8339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516134b7620003956000396000818161026d01528181610537015281816111730152818161199f01528181611bee015261206b0152600081816102310152611bc70152600081816102010152611ba00152600081816101d10152611b710152600081816112ee015261133a015260006113b501526134b76000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063ad7a22f81161008c578063f2fde38b11610066578063f2fde38b146104fa578063f47a86901461050d578063ff888fb11461052057600080fd5b8063ad7a22f8146104b4578063afcb95d7146104c7578063b1dc65a4146104e757600080fd5b80638da5cb5b116100bd5780638da5cb5b146104645780638db94e441461048c578063a7206cd61461049457600080fd5b806379ba50971461042457806381ff70481461042c5780638456cb591461045c57600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103b4578063666cab8d146103d05780637437ff9f146103e557600080fd5b806332048875146103795780633f4ba83a1461039a5780634120fccd146103a257600080fd5b8063181f5a7711610176578063181f5a77146103085780631ef381741461035157806329b980e41461036657600080fd5b806306285c691461019d5780630a6cd30d146102c057806310c374ed146102d8575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b79190612656565b60405180910390f35b6102c8610533565b60405190151581526020016102b7565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b6103446040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102b79190612713565b61036461035f366004612966565b6105ca565b005b610364610374366004612a33565b610deb565b61038c610387366004612aa6565b610e37565b6040519081526020016102b7565b610364610f2d565b60095467ffffffffffffffff166102ef565b6009546d0100000000000000000000000000900460ff166102c8565b6103d8610f93565b6040516102b79190612b6b565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b610364611002565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b6103646110ff565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6102c861116f565b61038c6104a2366004612b7e565b6000908152600a602052604090205490565b6103646104c2366004612b97565b611226565b6040805160018152600060208201819052918101919091526060016102b7565b6103646104f5366004612bb2565b611269565b610364610508366004612c97565b611889565b61036461051b366004612cb4565b61189d565b6102c861052e366004612b7e565b61193c565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612cf6565b15905090565b855185518560ff16601f831115610642576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106ac576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610639565b81831461073a576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610639565b610745816003612d47565b83116107ad576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610639565b6107b5611a10565b6107be86611a93565b60065460005b818110156108ba5760056000600683815481106107e3576107e3612d5e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061085357610853612d5e565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108b381612d8d565b90506107c4565b50895160005b81811015610c935760008c82815181106108dc576108dc612d5e565b60200260200101519050600060028111156108f9576108f9612dc5565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561093857610938612dc5565b1461099f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff81166109ec576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9c57610a9c612dc5565b021790555090505060008c8381518110610ab857610ab8612d5e565b6020026020010151905060006002811115610ad557610ad5612dc5565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b1457610b14612dc5565b14610b7b576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff8116610bc8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c7857610c78612dc5565b0217905550905050505080610c8c90612d8d565b90506108c0565b508a51610ca79060069060208e0190612598565b508951610cbb9060079060208d0190612598565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d41914691309190600090610d139063ffffffff16612df4565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611c4f565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610dd599989796959493929190612e17565b60405180910390a1505050505050505050505050565b610df3611a10565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610e88576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ef987878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611cfa915050565b9050610f048161193c565b610f12576000915050610f24565b6000908152600a602052604090205490505b95945050505050565b610f35611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610ff857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610fcd575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610639565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611107611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610f89565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190612cf6565b15801561122157506009546d0100000000000000000000000000900460ff16155b905090565b61122e611a10565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b611278878760208b013561201b565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146112eb5780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610639565b467f00000000000000000000000000000000000000000000000000000000000000001461136c576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610639565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561140e576002826020015183604001516113ef9190612ead565b6113f99190612ec6565b611404906001612ead565b60ff169050611424565b602082015161141e906001612ead565b60ff1690505b86811461145d576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611496576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156114d9576114d9612dc5565b60028111156114ea576114ea612dc5565b905250905060028160200151600281111561150757611507612dc5565b14801561154e57506007816000015160ff168154811061152957611529612d5e565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611584576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611592866020612d47565b61159d896020612d47565b6115a98c610144612f0f565b6115b39190612f0f565b6115bd9190612f0f565b9050368114611601576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610639565b5060008a8a604051611614929190612f22565b60405190819003812061162b918e90602001612f32565b60405160208183030381529060405280519060200120905061164b612622565b8860005b818110156118785760006001858a846020811061166e5761166e612d5e565b61167b91901a601b612ead565b8f8f8681811061168d5761168d612d5e565b905060200201358e8e878181106116a6576116a6612d5e565b90506020020135604051600081526020016040526040516116e3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611705573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561178857611788612dc5565b600281111561179957611799612dc5565b90525090506001816020015160028111156117b6576117b6612dc5565b146117ed576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061180457611804612d5e565b602002015115611840576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061185b5761185b612d5e565b9115156020909202015250611871905081612d8d565b905061164f565b505050505050505050505050505050565b611891611a10565b61189a81612428565b50565b6118a5611a10565b60005b818110156119375760008383838181106118c4576118c4612d5e565b9050602002013590506118d68161193c565b611926576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061191d9083815260200190565b60405180910390a15b5061193081612d8d565b90506118a8565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156119e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0a9190612cf6565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610639565b565b600081806020019051810190611aa99190612f46565b805190915073ffffffffffffffffffffffffffffffffffffffff16611afa576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391611c43918490612f92565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611c739998979695949392919061300f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611d3b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611d4f57506101018111155b611d85576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611de6576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611e135786600081518110611e0157611e01612d5e565b60200260200101519350505050612014565b60008167ffffffffffffffff811115611e2e57611e2e612726565b604051908082528060200260200182016040528015611e57578160200160208202803683370190505b50905060008080805b85811015611f9a5760006001821b8b811603611ebb5788851015611ea4578c5160018601958e918110611e9557611e95612d5e565b60200260200101519050611edd565b8551600185019487918110611e9557611e95612d5e565b8b5160018401938d918110611ed257611ed2612d5e565b602002602001015190505b600089861015611f0d578d5160018701968f918110611efe57611efe612d5e565b60200260200101519050611f2f565b8651600186019588918110611f2457611f24612d5e565b602002602001015190505b82851115611f69576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f73828261251d565b878481518110611f8557611f85612d5e565b60209081029190910101525050600101611e60565b506001850382148015611fac57508683145b8015611fb757508581145b611fed576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061200257612002612d5e565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615612069576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612cf6565b1561212f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061213d8385018561319b565b8051515190915015158061215657508051602001515115155b1561228e5760095464ffffffffff8084166801000000000000000090920416101561225357600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f9161220d916004016133ee565b600060405180830381600087803b15801561222757600080fd5b505af115801561223b573d6000803e3d6000fd5b50505050604081015161224e5750505050565b61228e565b604081015161228e576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806122c9575060208082015190810151905167ffffffffffffffff9182169116115b156123065780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106399190613401565b6040810151612341576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a60205220541561238a576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602080820151015161239d906001613426565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf59061241a90839061344e565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610639565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600081831061255f5760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612014565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612014565b828054828255906000526020600020908101928215612612579160200282015b8281111561261257825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125b8565b5061261e929150612641565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b8082111561261e5760008155600101612642565b60808101611a0a828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126d5576020818501810151868301820152016126b9565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061201460208301846126af565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561277857612778612726565b60405290565b6040516060810167ffffffffffffffff8111828210171561277857612778612726565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127e8576127e8612726565b604052919050565b600067ffffffffffffffff82111561280a5761280a612726565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461189a57600080fd5b600082601f83011261284757600080fd5b8135602061285c612857836127f0565b6127a1565b82815260059290921b8401810191818101908684111561287b57600080fd5b8286015b8481101561289f57803561289281612814565b835291830191830161287f565b509695505050505050565b803560ff811681146128bb57600080fd5b919050565b600082601f8301126128d157600080fd5b813567ffffffffffffffff8111156128eb576128eb612726565b61291c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127a1565b81815284602083860101111561293157600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146128bb57600080fd5b60008060008060008060c0878903121561297f57600080fd5b863567ffffffffffffffff8082111561299757600080fd5b6129a38a838b01612836565b975060208901359150808211156129b957600080fd5b6129c58a838b01612836565b96506129d360408a016128aa565b955060608901359150808211156129e957600080fd5b6129f58a838b016128c0565b9450612a0360808a0161294e565b935060a0890135915080821115612a1957600080fd5b50612a2689828a016128c0565b9150509295509295509295565b600060208284031215612a4557600080fd5b813564ffffffffff8116811461201457600080fd5b60008083601f840112612a6c57600080fd5b50813567ffffffffffffffff811115612a8457600080fd5b6020830191508360208260051b8501011115612a9f57600080fd5b9250929050565b600080600080600060608688031215612abe57600080fd5b853567ffffffffffffffff80821115612ad657600080fd5b612ae289838a01612a5a565b90975095506020880135915080821115612afb57600080fd5b50612b0888828901612a5a565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612b6057815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b2e565b509495945050505050565b6020815260006120146020830184612b1a565b600060208284031215612b9057600080fd5b5035919050565b600060208284031215612ba957600080fd5b6120148261294e565b60008060008060008060008060e0898b031215612bce57600080fd5b606089018a811115612bdf57600080fd5b8998503567ffffffffffffffff80821115612bf957600080fd5b818b0191508b601f830112612c0d57600080fd5b813581811115612c1c57600080fd5b8c6020828501011115612c2e57600080fd5b6020830199508098505060808b0135915080821115612c4c57600080fd5b612c588c838d01612a5a565b909750955060a08b0135915080821115612c7157600080fd5b50612c7e8b828c01612a5a565b999c989b50969995989497949560c00135949350505050565b600060208284031215612ca957600080fd5b813561201481612814565b60008060208385031215612cc757600080fd5b823567ffffffffffffffff811115612cde57600080fd5b612cea85828601612a5a565b90969095509350505050565b600060208284031215612d0857600080fd5b8151801515811461201457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a0a57611a0a612d18565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612dbe57612dbe612d18565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612e0d57612e0d612d18565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612e478184018a612b1a565b90508281036080840152612e5b8189612b1a565b905060ff871660a084015282810360c0840152612e7881876126af565b905067ffffffffffffffff851660e0840152828103610100840152612e9d81856126af565b9c9b505050505050505050505050565b60ff8181168382160190811115611a0a57611a0a612d18565b600060ff831680612f00577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a0a57611a0a612d18565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f5857600080fd5b6040516020810181811067ffffffffffffffff82111715612f7b57612f7b612726565b6040528251612f8981612814565b81529392505050565b60a08101612feb828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526130568285018b612b1a565b9150838203608085015261306a828a612b1a565b915060ff881660a085015283820360c085015261308782886126af565b90861660e08501528381036101008501529050612e9d81856126af565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146128bb57600080fd5b600082601f8301126130e157600080fd5b813560206130f1612857836127f0565b82815260069290921b8401810191818101908684111561311057600080fd5b8286015b8481101561289f576040818903121561312d5760008081fd5b613135612755565b61313e8261294e565b815261314b8583016130a4565b81860152835291830191604001613114565b60006040828403121561316f57600080fd5b613177612755565b90506131828261294e565b81526131906020830161294e565b602082015292915050565b600060208083850312156131ae57600080fd5b823567ffffffffffffffff808211156131c657600080fd5b90840190608082870312156131da57600080fd5b6131e261277e565b8235828111156131f157600080fd5b8301604081890381131561320457600080fd5b61320c612755565b82358581111561321b57600080fd5b8301601f81018b1361322c57600080fd5b803561323a612857826127f0565b81815260069190911b8201890190898101908d83111561325957600080fd5b928a01925b828410156132a95785848f0312156132765760008081fd5b61327e612755565b843561328981612814565b8152613296858d016130a4565b818d0152825292850192908a019061325e565b845250505082870135858111156132bf57600080fd5b6132cb8b8286016130d0565b828901525083526132de8986880161315d565b8684015260608501358184015250508094505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b81811015613373578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401929185019160010161331a565b50508583015187820388850152805180835290840192506000918401905b808310156133e2578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685830152928401926001929092019190850190613391565b50979650505050505050565b60208152600061201460208301846132fa565b60408101611a0a8284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561344757613447612d18565b5092915050565b60208152600082516080602084015261346a60a08401826132fa565b905060208401516134956040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000813000a", } var CommitStoreABI = CommitStoreMetaData.ABI @@ -1819,7 +1823,7 @@ func (CommitStorePaused) Topic() common.Hash { } func (CommitStoreReportAccepted) Topic() common.Hash { - return common.HexToHash("0xc14f9167b03b9a5725671c8678a54571219bff700e4a3665aef9e096c6a846f8") + return common.HexToHash("0x291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf5") } func (CommitStoreRootRemoved) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/commit_store_1_0_0/commit_store_1_0_0.go b/core/gethwrappers/ccip/generated/commit_store_1_0_0/commit_store_1_0_0.go new file mode 100644 index 0000000000..d5d1988bbe --- /dev/null +++ b/core/gethwrappers/ccip/generated/commit_store_1_0_0/commit_store_1_0_0.go @@ -0,0 +1,1951 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package commit_store_1_0_0 + +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 CommitStoreCommitReport struct { + PriceUpdates InternalPriceUpdates + Interval CommitStoreInterval + MerkleRoot [32]byte +} + +type CommitStoreDynamicConfig struct { + PriceRegistry common.Address +} + +type CommitStoreInterval struct { + Min uint64 + Max uint64 +} + +type CommitStoreStaticConfig struct { + ChainSelector uint64 + SourceChainSelector uint64 + OnRamp common.Address + ArmProxy common.Address +} + +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + +type InternalTokenPriceUpdate struct { + SourceToken common.Address + UsdPerToken *big.Int +} + +var CommitStoreMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":\"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\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint192\",\"name\":\"usdPerToken\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint192\",\"name\":\"usdPerUnitGas\",\"type\":\"uint192\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"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\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b5060405162003788380380620037888339810160408190526200004d9162000272565b600033808281620000a55760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d857620000d88162000192565b50505015156080524660a05260408101516001600160a01b0316158062000107575080516001600160401b0316155b806200011e575060208101516001600160401b0316155b8062000135575060608101516001600160a01b0316155b156200015457604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b0390811661010052606090910151166101205262000306565b336001600160a01b03821603620001ec5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009c565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025557600080fd5b919050565b80516001600160a01b03811681146200025557600080fd5b6000608082840312156200028557600080fd5b604051608081016001600160401b0381118282101715620002b657634e487b7160e01b600052604160045260246000fd5b604052620002c4836200023d565b8152620002d4602084016200023d565b6020820152620002e7604084016200025a565b6040820152620002fa606084016200025a565b60608201529392505050565b60805160a05160c05160e05161010051610120516133f3620003956000396000818161026d01528181610537015281816111730152818161199f01528181611bee015261206b0152600081816102310152611bc70152600081816102010152611ba00152600081816101d10152611b710152600081816112ee015261133a015260006113b501526133f36000f3fe608060405234801561001057600080fd5b50600436106101985760003560e01c806379ba5097116100e3578063ad7a22f81161008c578063f2fde38b11610066578063f2fde38b146104fa578063f47a86901461050d578063ff888fb11461052057600080fd5b8063ad7a22f8146104b4578063afcb95d7146104c7578063b1dc65a4146104e757600080fd5b80638da5cb5b116100bd5780638da5cb5b146104645780638db94e441461048c578063a7206cd61461049457600080fd5b806379ba50971461042457806381ff70481461042c5780638456cb591461045c57600080fd5b806332048875116101455780635c975abb1161011f5780635c975abb146103b4578063666cab8d146103d05780637437ff9f146103e557600080fd5b806332048875146103795780633f4ba83a1461039a5780634120fccd146103a257600080fd5b8063181f5a7711610176578063181f5a77146103085780631ef381741461035157806329b980e41461036657600080fd5b806306285c691461019d5780630a6cd30d146102c057806310c374ed146102d8575b600080fd5b6102aa60408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102b7919061265f565b60405180910390f35b6102c8610533565b60405190151581526020016102b7565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102b7565b6103446040518060400160405280601181526020017f436f6d6d697453746f726520312e302e3000000000000000000000000000000081525081565b6040516102b7919061271c565b61036461035f36600461296f565b6105ca565b005b610364610374366004612a3c565b610deb565b61038c610387366004612aaf565b610e37565b6040519081526020016102b7565b610364610f2d565b60095467ffffffffffffffff166102ef565b6009546d0100000000000000000000000000900460ff166102c8565b6103d8610f93565b6040516102b79190612b74565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102b7565b610364611002565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102b7565b6103646110ff565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102b7565b6102c861116f565b61038c6104a2366004612b87565b6000908152600a602052604090205490565b6103646104c2366004612ba0565b611226565b6040805160018152600060208201819052918101919091526060016102b7565b6103646104f5366004612bbb565b611269565b610364610508366004612ca0565b611889565b61036461051b366004612cbd565b61189d565b6102c861052e366004612b87565b61193c565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c49190612cff565b15905090565b855185518560ff16601f831115610642576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106ac576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610639565b81831461073a576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610639565b610745816003612d50565b83116107ad576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610639565b6107b5611a10565b6107be86611a93565b60065460005b818110156108ba5760056000600683815481106107e3576107e3612d67565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061085357610853612d67565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108b381612d96565b90506107c4565b50895160005b81811015610c935760008c82815181106108dc576108dc612d67565b60200260200101519050600060028111156108f9576108f9612dce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561093857610938612dce565b1461099f576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff81166109ec576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610a9c57610a9c612dce565b021790555090505060008c8381518110610ab857610ab8612d67565b6020026020010151905060006002811115610ad557610ad5612dce565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b1457610b14612dce565b14610b7b576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610639565b73ffffffffffffffffffffffffffffffffffffffff8116610bc8576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c7857610c78612dce565b0217905550905050505080610c8c90612d96565b90506108c0565b508a51610ca79060069060208e01906125a1565b508951610cbb9060079060208d01906125a1565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d41914691309190600090610d139063ffffffff16612dfd565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e611c4f565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610dd599989796959493929190612e20565b60405180910390a1505050505050505050505050565b610df3611a10565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610e88576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610ef987878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250611cfa915050565b9050610f048161193c565b610f12576000915050610f24565b6000908152600a602052604090205490505b95945050505050565b610f35611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b60606007805480602002602001604051908101604052809291908181526020018280548015610ff857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610fcd575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314611083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610639565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611107611a10565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610f89565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111dc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112009190612cff565b15801561122157506009546d0100000000000000000000000000900460ff16155b905090565b61122e611a10565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b611278878760208b013561201b565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146112eb5780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610639565b467f00000000000000000000000000000000000000000000000000000000000000001461136c576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610639565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561140e576002826020015183604001516113ef9190612eb6565b6113f99190612ecf565b611404906001612eb6565b60ff169050611424565b602082015161141e906001612eb6565b60ff1690505b86811461145d576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b868514611496576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff808216845292939192918401916101009091041660028111156114d9576114d9612dce565b60028111156114ea576114ea612dce565b905250905060028160200151600281111561150757611507612dce565b14801561154e57506007816000015160ff168154811061152957611529612d67565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611584576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611592866020612d50565b61159d896020612d50565b6115a98c610144612f18565b6115b39190612f18565b6115bd9190612f18565b9050368114611601576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610639565b5060008a8a604051611614929190612f2b565b60405190819003812061162b918e90602001612f3b565b60405160208183030381529060405280519060200120905061164b61262b565b8860005b818110156118785760006001858a846020811061166e5761166e612d67565b61167b91901a601b612eb6565b8f8f8681811061168d5761168d612d67565b905060200201358e8e878181106116a6576116a6612d67565b90506020020135604051600081526020016040526040516116e3949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611705573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff808216865293975091955092939284019161010090910416600281111561178857611788612dce565b600281111561179957611799612dce565b90525090506001816020015160028111156117b6576117b6612dce565b146117ed576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061180457611804612d67565b602002015115611840576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061185b5761185b612d67565b9115156020909202015250611871905081612d96565b905061164f565b505050505050505050505050505050565b611891611a10565b61189a81612431565b50565b6118a5611a10565b60005b818110156119375760008383838181106118c4576118c4612d67565b9050602002013590506118d68161193c565b611926576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061191d9083815260200190565b60405180910390a15b5061193081612d96565b90506118a8565b505050565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa1580156119e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a0a9190612cff565b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611a91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610639565b565b600081806020019051810190611aa99190612f4f565b805190915073ffffffffffffffffffffffffffffffffffffffff16611afa576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391611c43918490612f9b565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a604051602001611c7399989796959493929190613018565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303611d3b576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6101018211801590611d4f57506101018111155b611d85576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115611de6576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003611e135786600081518110611e0157611e01612d67565b60200260200101519350505050612014565b60008167ffffffffffffffff811115611e2e57611e2e61272f565b604051908082528060200260200182016040528015611e57578160200160208202803683370190505b50905060008080805b85811015611f9a5760006001821b8b811603611ebb5788851015611ea4578c5160018601958e918110611e9557611e95612d67565b60200260200101519050611edd565b8551600185019487918110611e9557611e95612d67565b8b5160018401938d918110611ed257611ed2612d67565b602002602001015190505b600089861015611f0d578d5160018701968f918110611efe57611efe612d67565b60200260200101519050611f2f565b8651600186019588918110611f2457611f24612d67565b602002602001015190505b82851115611f69576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f738282612526565b878481518110611f8557611f85612d67565b60209081029190910101525050600101611e60565b506001850382148015611fac57508683145b8015611fb757508581145b611fed576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061200257612002612d67565b60200260200101519750505050505050505b9392505050565b6009546d0100000000000000000000000000900460ff1615612069576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120f89190612cff565b1561212f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061213d83850185613113565b8051515190915015158061215f575080516020015167ffffffffffffffff1615155b156122975760095464ffffffffff8084166801000000000000000090920416101561225c57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f866548c900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092169163866548c9916122169160040161332a565b600060405180830381600087803b15801561223057600080fd5b505af1158015612244573d6000803e3d6000fd5b5050505060408101516122575750505050565b612297565b6040810151612297576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff90811691161415806122d2575060208082015190810151905167ffffffffffffffff9182169116115b1561230f5780602001516040517fbb1ae18d000000000000000000000000000000000000000000000000000000008152600401610639919061333d565b604081015161234a576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415612393576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208082015101516123a6906001613362565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517fe81b49e583122eb290c46fc255c962b9a2dec468816c00fb7a2e6ebc42dc92d49061242390839061338a565b60405180910390a150505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124b0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610639565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106125685760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612014565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612014565b82805482825590600052602060002090810192821561261b579160200282015b8281111561261b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125c1565b5061262792915061264a565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115612627576000815560010161264b565b60808101611a0a828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126de576020818501810151868301820152016126c2565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061201460208301846126b8565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156127815761278161272f565b60405290565b6040516060810167ffffffffffffffff811182821017156127815761278161272f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127f1576127f161272f565b604052919050565b600067ffffffffffffffff8211156128135761281361272f565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff8116811461189a57600080fd5b600082601f83011261285057600080fd5b81356020612865612860836127f9565b6127aa565b82815260059290921b8401810191818101908684111561288457600080fd5b8286015b848110156128a857803561289b8161281d565b8352918301918301612888565b509695505050505050565b803560ff811681146128c457600080fd5b919050565b600082601f8301126128da57600080fd5b813567ffffffffffffffff8111156128f4576128f461272f565b61292560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016127aa565b81815284602083860101111561293a57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146128c457600080fd5b60008060008060008060c0878903121561298857600080fd5b863567ffffffffffffffff808211156129a057600080fd5b6129ac8a838b0161283f565b975060208901359150808211156129c257600080fd5b6129ce8a838b0161283f565b96506129dc60408a016128b3565b955060608901359150808211156129f257600080fd5b6129fe8a838b016128c9565b9450612a0c60808a01612957565b935060a0890135915080821115612a2257600080fd5b50612a2f89828a016128c9565b9150509295509295509295565b600060208284031215612a4e57600080fd5b813564ffffffffff8116811461201457600080fd5b60008083601f840112612a7557600080fd5b50813567ffffffffffffffff811115612a8d57600080fd5b6020830191508360208260051b8501011115612aa857600080fd5b9250929050565b600080600080600060608688031215612ac757600080fd5b853567ffffffffffffffff80821115612adf57600080fd5b612aeb89838a01612a63565b90975095506020880135915080821115612b0457600080fd5b50612b1188828901612a63565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612b6957815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612b37565b509495945050505050565b6020815260006120146020830184612b23565b600060208284031215612b9957600080fd5b5035919050565b600060208284031215612bb257600080fd5b61201482612957565b60008060008060008060008060e0898b031215612bd757600080fd5b606089018a811115612be857600080fd5b8998503567ffffffffffffffff80821115612c0257600080fd5b818b0191508b601f830112612c1657600080fd5b813581811115612c2557600080fd5b8c6020828501011115612c3757600080fd5b6020830199508098505060808b0135915080821115612c5557600080fd5b612c618c838d01612a63565b909750955060a08b0135915080821115612c7a57600080fd5b50612c878b828c01612a63565b999c989b50969995989497949560c00135949350505050565b600060208284031215612cb257600080fd5b81356120148161281d565b60008060208385031215612cd057600080fd5b823567ffffffffffffffff811115612ce757600080fd5b612cf385828601612a63565b90969095509350505050565b600060208284031215612d1157600080fd5b8151801515811461201457600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a0a57611a0a612d21565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612dc757612dc7612d21565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612e1657612e16612d21565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612e508184018a612b23565b90508281036080840152612e648189612b23565b905060ff871660a084015282810360c0840152612e8181876126b8565b905067ffffffffffffffff851660e0840152828103610100840152612ea681856126b8565b9c9b505050505050505050505050565b60ff8181168382160190811115611a0a57611a0a612d21565b600060ff831680612f09577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a0a57611a0a612d21565b8183823760009101908152919050565b828152606082602083013760800192915050565b600060208284031215612f6157600080fd5b6040516020810181811067ffffffffffffffff82111715612f8457612f8461272f565b6040528251612f928161281d565b81529392505050565b60a08101612ff4828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b16604085015281606085015261305f8285018b612b23565b91508382036080850152613073828a612b23565b915060ff881660a085015283820360c085015261309082886126b8565b90861660e08501528381036101008501529050612ea681856126b8565b803577ffffffffffffffffffffffffffffffffffffffffffffffff811681146128c457600080fd5b6000604082840312156130e757600080fd5b6130ef61275e565b90506130fa82612957565b815261310860208301612957565b602082015292915050565b6000602080838503121561312657600080fd5b823567ffffffffffffffff8082111561313e57600080fd5b908401906080828703121561315257600080fd5b61315a612787565b82358281111561316957600080fd5b83016060818903121561317b57600080fd5b613183612787565b81358481111561319257600080fd5b82019350601f840189136131a557600080fd5b83356131b3612860826127f9565b81815260069190911b8501870190878101908b8311156131d257600080fd5b958801955b82871015613226576040878d0312156131f05760008081fd5b6131f861275e565b87356132038161281d565b8152613210888b016130ad565b818b0152825260409690960195908801906131d7565b8352506132369050828701612957565b86820152613246604083016130ad565b604082015282525061325a878486016130d5565b93810193909352506060013560408201529392505050565b805160608084528151908401819052600091602091908201906080860190845b818110156132e9578351805173ffffffffffffffffffffffffffffffffffffffff16845285015177ffffffffffffffffffffffffffffffffffffffffffffffff168584015292840192604090920191600101613292565b505067ffffffffffffffff83860151168387015260408501519250610f24604087018477ffffffffffffffffffffffffffffffffffffffffffffffff169052565b6020815260006120146020830184613272565b60408101611a0a8284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338357613383612d21565b5092915050565b6020815260008251608060208401526133a660a0840182613272565b905060208401516133d16040850182805167ffffffffffffffff908116835260209182015116910152565b5060408401516080840152809150509291505056fea164736f6c6343000813000a", +} + +var CommitStoreABI = CommitStoreMetaData.ABI + +var CommitStoreBin = CommitStoreMetaData.Bin + +func DeployCommitStore(auth *bind.TransactOpts, backend bind.ContractBackend, staticConfig CommitStoreStaticConfig) (common.Address, *types.Transaction, *CommitStore, error) { + parsed, err := CommitStoreMetaData.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(CommitStoreBin), backend, staticConfig) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &CommitStore{CommitStoreCaller: CommitStoreCaller{contract: contract}, CommitStoreTransactor: CommitStoreTransactor{contract: contract}, CommitStoreFilterer: CommitStoreFilterer{contract: contract}}, nil +} + +type CommitStore struct { + address common.Address + abi abi.ABI + CommitStoreCaller + CommitStoreTransactor + CommitStoreFilterer +} + +type CommitStoreCaller struct { + contract *bind.BoundContract +} + +type CommitStoreTransactor struct { + contract *bind.BoundContract +} + +type CommitStoreFilterer struct { + contract *bind.BoundContract +} + +type CommitStoreSession struct { + Contract *CommitStore + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type CommitStoreCallerSession struct { + Contract *CommitStoreCaller + CallOpts bind.CallOpts +} + +type CommitStoreTransactorSession struct { + Contract *CommitStoreTransactor + TransactOpts bind.TransactOpts +} + +type CommitStoreRaw struct { + Contract *CommitStore +} + +type CommitStoreCallerRaw struct { + Contract *CommitStoreCaller +} + +type CommitStoreTransactorRaw struct { + Contract *CommitStoreTransactor +} + +func NewCommitStore(address common.Address, backend bind.ContractBackend) (*CommitStore, error) { + abi, err := abi.JSON(strings.NewReader(CommitStoreABI)) + if err != nil { + return nil, err + } + contract, err := bindCommitStore(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &CommitStore{address: address, abi: abi, CommitStoreCaller: CommitStoreCaller{contract: contract}, CommitStoreTransactor: CommitStoreTransactor{contract: contract}, CommitStoreFilterer: CommitStoreFilterer{contract: contract}}, nil +} + +func NewCommitStoreCaller(address common.Address, caller bind.ContractCaller) (*CommitStoreCaller, error) { + contract, err := bindCommitStore(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &CommitStoreCaller{contract: contract}, nil +} + +func NewCommitStoreTransactor(address common.Address, transactor bind.ContractTransactor) (*CommitStoreTransactor, error) { + contract, err := bindCommitStore(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &CommitStoreTransactor{contract: contract}, nil +} + +func NewCommitStoreFilterer(address common.Address, filterer bind.ContractFilterer) (*CommitStoreFilterer, error) { + contract, err := bindCommitStore(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &CommitStoreFilterer{contract: contract}, nil +} + +func bindCommitStore(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := CommitStoreMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_CommitStore *CommitStoreRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStore.Contract.CommitStoreCaller.contract.Call(opts, result, method, params...) +} + +func (_CommitStore *CommitStoreRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.Contract.CommitStoreTransactor.contract.Transfer(opts) +} + +func (_CommitStore *CommitStoreRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStore.Contract.CommitStoreTransactor.contract.Transact(opts, method, params...) +} + +func (_CommitStore *CommitStoreCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _CommitStore.Contract.contract.Call(opts, result, method, params...) +} + +func (_CommitStore *CommitStoreTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.Contract.contract.Transfer(opts) +} + +func (_CommitStore *CommitStoreTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _CommitStore.Contract.contract.Transact(opts, method, params...) +} + +func (_CommitStore *CommitStoreCaller) GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getDynamicConfig") + + if err != nil { + return *new(CommitStoreDynamicConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreDynamicConfig)).(*CommitStoreDynamicConfig) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStore.Contract.GetDynamicConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetDynamicConfig() (CommitStoreDynamicConfig, error) { + return _CommitStore.Contract.GetDynamicConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getExpectedNextSequenceNumber") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStore.Contract.GetExpectedNextSequenceNumber(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetExpectedNextSequenceNumber() (uint64, error) { + return _CommitStore.Contract.GetExpectedNextSequenceNumber(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getLatestPriceEpochAndRound") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStore.Contract.GetLatestPriceEpochAndRound(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetLatestPriceEpochAndRound() (uint64, error) { + return _CommitStore.Contract.GetLatestPriceEpochAndRound(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getMerkleRoot", root) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStore.Contract.GetMerkleRoot(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCallerSession) GetMerkleRoot(root [32]byte) (*big.Int, error) { + return _CommitStore.Contract.GetMerkleRoot(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCaller) GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getStaticConfig") + + if err != nil { + return *new(CommitStoreStaticConfig), err + } + + out0 := *abi.ConvertType(out[0], new(CommitStoreStaticConfig)).(*CommitStoreStaticConfig) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStore.Contract.GetStaticConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetStaticConfig() (CommitStoreStaticConfig, error) { + return _CommitStore.Contract.GetStaticConfig(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "getTransmitters") + + if err != nil { + return *new([]common.Address), err + } + + out0 := *abi.ConvertType(out[0], new([]common.Address)).(*[]common.Address) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) GetTransmitters() ([]common.Address, error) { + return _CommitStore.Contract.GetTransmitters(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) GetTransmitters() ([]common.Address, error) { + return _CommitStore.Contract.GetTransmitters(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) IsARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsARMHealthy() (bool, error) { + return _CommitStore.Contract.IsARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) IsARMHealthy() (bool, error) { + return _CommitStore.Contract.IsARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isBlessed", root) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStore.Contract.IsBlessed(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCallerSession) IsBlessed(root [32]byte) (bool, error) { + return _CommitStore.Contract.IsBlessed(&_CommitStore.CallOpts, root) +} + +func (_CommitStore *CommitStoreCaller) IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "isUnpausedAndARMHealthy") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStore.Contract.IsUnpausedAndARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) IsUnpausedAndARMHealthy() (bool, error) { + return _CommitStore.Contract.IsUnpausedAndARMHealthy(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) { + var out []interface{} + err := _CommitStore.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 (_CommitStore *CommitStoreSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStore.Contract.LatestConfigDetails(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) LatestConfigDetails() (LatestConfigDetails, + + error) { + return _CommitStore.Contract.LatestConfigDetails(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) { + var out []interface{} + err := _CommitStore.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 (_CommitStore *CommitStoreSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStore.Contract.LatestConfigDigestAndEpoch(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) LatestConfigDigestAndEpoch() (LatestConfigDigestAndEpoch, + + error) { + return _CommitStore.Contract.LatestConfigDigestAndEpoch(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _CommitStore.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 (_CommitStore *CommitStoreSession) Owner() (common.Address, error) { + return _CommitStore.Contract.Owner(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) Owner() (common.Address, error) { + return _CommitStore.Contract.Owner(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Paused(opts *bind.CallOpts) (bool, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "paused") + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Paused() (bool, error) { + return _CommitStore.Contract.Paused(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) Paused() (bool, error) { + return _CommitStore.Contract.Paused(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) TypeAndVersion() (string, error) { + return _CommitStore.Contract.TypeAndVersion(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCallerSession) TypeAndVersion() (string, error) { + return _CommitStore.Contract.TypeAndVersion(&_CommitStore.CallOpts) +} + +func (_CommitStore *CommitStoreCaller) Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + var out []interface{} + err := _CommitStore.contract.Call(opts, &out, "verify", hashedLeaves, proofs, proofFlagBits) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_CommitStore *CommitStoreSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStore.Contract.Verify(&_CommitStore.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStore *CommitStoreCallerSession) Verify(hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) { + return _CommitStore.Contract.Verify(&_CommitStore.CallOpts, hashedLeaves, proofs, proofFlagBits) +} + +func (_CommitStore *CommitStoreTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "acceptOwnership") +} + +func (_CommitStore *CommitStoreSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStore.Contract.AcceptOwnership(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _CommitStore.Contract.AcceptOwnership(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactor) Pause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "pause") +} + +func (_CommitStore *CommitStoreSession) Pause() (*types.Transaction, error) { + return _CommitStore.Contract.Pause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) Pause() (*types.Transaction, error) { + return _CommitStore.Contract.Pause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactor) ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "resetUnblessedRoots", rootToReset) +} + +func (_CommitStore *CommitStoreSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.ResetUnblessedRoots(&_CommitStore.TransactOpts, rootToReset) +} + +func (_CommitStore *CommitStoreTransactorSession) ResetUnblessedRoots(rootToReset [][32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.ResetUnblessedRoots(&_CommitStore.TransactOpts, rootToReset) +} + +func (_CommitStore *CommitStoreTransactor) SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setLatestPriceEpochAndRound", latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.Contract.SetLatestPriceEpochAndRound(&_CommitStore.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreTransactorSession) SetLatestPriceEpochAndRound(latestPriceEpochAndRound *big.Int) (*types.Transaction, error) { + return _CommitStore.Contract.SetLatestPriceEpochAndRound(&_CommitStore.TransactOpts, latestPriceEpochAndRound) +} + +func (_CommitStore *CommitStoreTransactor) SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setMinSeqNr", minSeqNr) +} + +func (_CommitStore *CommitStoreSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.Contract.SetMinSeqNr(&_CommitStore.TransactOpts, minSeqNr) +} + +func (_CommitStore *CommitStoreTransactorSession) SetMinSeqNr(minSeqNr uint64) (*types.Transaction, error) { + return _CommitStore.Contract.SetMinSeqNr(&_CommitStore.TransactOpts, minSeqNr) +} + +func (_CommitStore *CommitStoreTransactor) SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "setOCR2Config", signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.Contract.SetOCR2Config(&_CommitStore.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreTransactorSession) SetOCR2Config(signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) { + return _CommitStore.Contract.SetOCR2Config(&_CommitStore.TransactOpts, signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig) +} + +func (_CommitStore *CommitStoreTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "transferOwnership", to) +} + +func (_CommitStore *CommitStoreSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStore.Contract.TransferOwnership(&_CommitStore.TransactOpts, to) +} + +func (_CommitStore *CommitStoreTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _CommitStore.Contract.TransferOwnership(&_CommitStore.TransactOpts, to) +} + +func (_CommitStore *CommitStoreTransactor) Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "transmit", reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.Transmit(&_CommitStore.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreTransactorSession) Transmit(reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) { + return _CommitStore.Contract.Transmit(&_CommitStore.TransactOpts, reportContext, report, rs, ss, rawVs) +} + +func (_CommitStore *CommitStoreTransactor) Unpause(opts *bind.TransactOpts) (*types.Transaction, error) { + return _CommitStore.contract.Transact(opts, "unpause") +} + +func (_CommitStore *CommitStoreSession) Unpause() (*types.Transaction, error) { + return _CommitStore.Contract.Unpause(&_CommitStore.TransactOpts) +} + +func (_CommitStore *CommitStoreTransactorSession) Unpause() (*types.Transaction, error) { + return _CommitStore.Contract.Unpause(&_CommitStore.TransactOpts) +} + +type CommitStoreConfigSetIterator struct { + Event *CommitStoreConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreConfigSetIterator) Error() error { + return it.fail +} + +func (it *CommitStoreConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreConfigSet struct { + StaticConfig CommitStoreStaticConfig + DynamicConfig CommitStoreDynamicConfig + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreConfigSetIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &CommitStoreConfigSetIterator{contract: _CommitStore.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet) (event.Subscription, error) { + + logs, sub, err := _CommitStore.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(CommitStoreConfigSet) + if err := _CommitStore.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 (_CommitStore *CommitStoreFilterer) ParseConfigSet(log types.Log) (*CommitStoreConfigSet, error) { + event := new(CommitStoreConfigSet) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreConfigSet0Iterator struct { + Event *CommitStoreConfigSet0 + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreConfigSet0Iterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreConfigSet0) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreConfigSet0Iterator) Error() error { + return it.fail +} + +func (it *CommitStoreConfigSet0Iterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreConfigSet0 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 (_CommitStore *CommitStoreFilterer) FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreConfigSet0Iterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return &CommitStoreConfigSet0Iterator{contract: _CommitStore.contract, event: "ConfigSet0", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet0) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ConfigSet0") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreConfigSet0) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseConfigSet0(log types.Log) (*CommitStoreConfigSet0, error) { + event := new(CommitStoreConfigSet0) + if err := _CommitStore.contract.UnpackLog(event, "ConfigSet0", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreOwnershipTransferRequestedIterator struct { + Event *CommitStoreOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferRequestedIterator, 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 := _CommitStore.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreOwnershipTransferRequestedIterator{contract: _CommitStore.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferRequested, 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 := _CommitStore.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(CommitStoreOwnershipTransferRequested) + if err := _CommitStore.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 (_CommitStore *CommitStoreFilterer) ParseOwnershipTransferRequested(log types.Log) (*CommitStoreOwnershipTransferRequested, error) { + event := new(CommitStoreOwnershipTransferRequested) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreOwnershipTransferredIterator struct { + Event *CommitStoreOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *CommitStoreOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferredIterator, 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 := _CommitStore.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &CommitStoreOwnershipTransferredIterator{contract: _CommitStore.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferred, 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 := _CommitStore.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(CommitStoreOwnershipTransferred) + if err := _CommitStore.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 (_CommitStore *CommitStoreFilterer) ParseOwnershipTransferred(log types.Log) (*CommitStoreOwnershipTransferred, error) { + event := new(CommitStoreOwnershipTransferred) + if err := _CommitStore.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStorePausedIterator struct { + Event *CommitStorePaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStorePausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStorePaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStorePaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStorePausedIterator) Error() error { + return it.fail +} + +func (it *CommitStorePausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStorePaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterPaused(opts *bind.FilterOpts) (*CommitStorePausedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Paused") + if err != nil { + return nil, err + } + return &CommitStorePausedIterator{contract: _CommitStore.contract, event: "Paused", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStorePaused) (event.Subscription, error) { + + logs, sub, err := _CommitStore.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(CommitStorePaused) + if err := _CommitStore.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 (_CommitStore *CommitStoreFilterer) ParsePaused(log types.Log) (*CommitStorePaused, error) { + event := new(CommitStorePaused) + if err := _CommitStore.contract.UnpackLog(event, "Paused", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreReportAcceptedIterator struct { + Event *CommitStoreReportAccepted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreReportAcceptedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreReportAccepted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreReportAcceptedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreReportAcceptedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreReportAccepted struct { + Report CommitStoreCommitReport + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreReportAcceptedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return &CommitStoreReportAcceptedIterator{contract: _CommitStore.contract, event: "ReportAccepted", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreReportAccepted) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "ReportAccepted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreReportAccepted) + if err := _CommitStore.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseReportAccepted(log types.Log) (*CommitStoreReportAccepted, error) { + event := new(CommitStoreReportAccepted) + if err := _CommitStore.contract.UnpackLog(event, "ReportAccepted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreRootRemovedIterator struct { + Event *CommitStoreRootRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreRootRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreRootRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreRootRemovedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreRootRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreRootRemoved struct { + Root [32]byte + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreRootRemovedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return &CommitStoreRootRemovedIterator{contract: _CommitStore.contract, event: "RootRemoved", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreRootRemoved) (event.Subscription, error) { + + logs, sub, err := _CommitStore.contract.WatchLogs(opts, "RootRemoved") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(CommitStoreRootRemoved) + if err := _CommitStore.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_CommitStore *CommitStoreFilterer) ParseRootRemoved(log types.Log) (*CommitStoreRootRemoved, error) { + event := new(CommitStoreRootRemoved) + if err := _CommitStore.contract.UnpackLog(event, "RootRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreTransmittedIterator struct { + Event *CommitStoreTransmitted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreTransmittedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreTransmitted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreTransmittedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreTransmittedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreTransmitted struct { + ConfigDigest [32]byte + Epoch uint32 + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreTransmittedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Transmitted") + if err != nil { + return nil, err + } + return &CommitStoreTransmittedIterator{contract: _CommitStore.contract, event: "Transmitted", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreTransmitted) (event.Subscription, error) { + + logs, sub, err := _CommitStore.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(CommitStoreTransmitted) + if err := _CommitStore.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 (_CommitStore *CommitStoreFilterer) ParseTransmitted(log types.Log) (*CommitStoreTransmitted, error) { + event := new(CommitStoreTransmitted) + if err := _CommitStore.contract.UnpackLog(event, "Transmitted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type CommitStoreUnpausedIterator struct { + Event *CommitStoreUnpaused + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *CommitStoreUnpausedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(CommitStoreUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(CommitStoreUnpaused) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *CommitStoreUnpausedIterator) Error() error { + return it.fail +} + +func (it *CommitStoreUnpausedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type CommitStoreUnpaused struct { + Account common.Address + Raw types.Log +} + +func (_CommitStore *CommitStoreFilterer) FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreUnpausedIterator, error) { + + logs, sub, err := _CommitStore.contract.FilterLogs(opts, "Unpaused") + if err != nil { + return nil, err + } + return &CommitStoreUnpausedIterator{contract: _CommitStore.contract, event: "Unpaused", logs: logs, sub: sub}, nil +} + +func (_CommitStore *CommitStoreFilterer) WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreUnpaused) (event.Subscription, error) { + + logs, sub, err := _CommitStore.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(CommitStoreUnpaused) + if err := _CommitStore.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 (_CommitStore *CommitStoreFilterer) ParseUnpaused(log types.Log) (*CommitStoreUnpaused, error) { + event := new(CommitStoreUnpaused) + if err := _CommitStore.contract.UnpackLog(event, "Unpaused", 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 (_CommitStore *CommitStore) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _CommitStore.abi.Events["ConfigSet"].ID: + return _CommitStore.ParseConfigSet(log) + case _CommitStore.abi.Events["ConfigSet0"].ID: + return _CommitStore.ParseConfigSet0(log) + case _CommitStore.abi.Events["OwnershipTransferRequested"].ID: + return _CommitStore.ParseOwnershipTransferRequested(log) + case _CommitStore.abi.Events["OwnershipTransferred"].ID: + return _CommitStore.ParseOwnershipTransferred(log) + case _CommitStore.abi.Events["Paused"].ID: + return _CommitStore.ParsePaused(log) + case _CommitStore.abi.Events["ReportAccepted"].ID: + return _CommitStore.ParseReportAccepted(log) + case _CommitStore.abi.Events["RootRemoved"].ID: + return _CommitStore.ParseRootRemoved(log) + case _CommitStore.abi.Events["Transmitted"].ID: + return _CommitStore.ParseTransmitted(log) + case _CommitStore.abi.Events["Unpaused"].ID: + return _CommitStore.ParseUnpaused(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (CommitStoreConfigSet) Topic() common.Hash { + return common.HexToHash("0xc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec3") +} + +func (CommitStoreConfigSet0) Topic() common.Hash { + return common.HexToHash("0x1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e05") +} + +func (CommitStoreOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (CommitStoreOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (CommitStorePaused) Topic() common.Hash { + return common.HexToHash("0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258") +} + +func (CommitStoreReportAccepted) Topic() common.Hash { + return common.HexToHash("0xe81b49e583122eb290c46fc255c962b9a2dec468816c00fb7a2e6ebc42dc92d4") +} + +func (CommitStoreRootRemoved) Topic() common.Hash { + return common.HexToHash("0x202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f12") +} + +func (CommitStoreTransmitted) Topic() common.Hash { + return common.HexToHash("0xb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62") +} + +func (CommitStoreUnpaused) Topic() common.Hash { + return common.HexToHash("0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa") +} + +func (_CommitStore *CommitStore) Address() common.Address { + return _CommitStore.address +} + +type CommitStoreInterface interface { + GetDynamicConfig(opts *bind.CallOpts) (CommitStoreDynamicConfig, error) + + GetExpectedNextSequenceNumber(opts *bind.CallOpts) (uint64, error) + + GetLatestPriceEpochAndRound(opts *bind.CallOpts) (uint64, error) + + GetMerkleRoot(opts *bind.CallOpts, root [32]byte) (*big.Int, error) + + GetStaticConfig(opts *bind.CallOpts) (CommitStoreStaticConfig, error) + + GetTransmitters(opts *bind.CallOpts) ([]common.Address, error) + + IsARMHealthy(opts *bind.CallOpts) (bool, error) + + IsBlessed(opts *bind.CallOpts, root [32]byte) (bool, error) + + IsUnpausedAndARMHealthy(opts *bind.CallOpts) (bool, error) + + LatestConfigDetails(opts *bind.CallOpts) (LatestConfigDetails, + + error) + + LatestConfigDigestAndEpoch(opts *bind.CallOpts) (LatestConfigDigestAndEpoch, + + error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + Paused(opts *bind.CallOpts) (bool, error) + + TypeAndVersion(opts *bind.CallOpts) (string, error) + + Verify(opts *bind.CallOpts, hashedLeaves [][32]byte, proofs [][32]byte, proofFlagBits *big.Int) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + Pause(opts *bind.TransactOpts) (*types.Transaction, error) + + ResetUnblessedRoots(opts *bind.TransactOpts, rootToReset [][32]byte) (*types.Transaction, error) + + SetLatestPriceEpochAndRound(opts *bind.TransactOpts, latestPriceEpochAndRound *big.Int) (*types.Transaction, error) + + SetMinSeqNr(opts *bind.TransactOpts, minSeqNr uint64) (*types.Transaction, error) + + SetOCR2Config(opts *bind.TransactOpts, signers []common.Address, transmitters []common.Address, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + Transmit(opts *bind.TransactOpts, reportContext [3][32]byte, report []byte, rs [][32]byte, ss [][32]byte, rawVs [32]byte) (*types.Transaction, error) + + Unpause(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*CommitStoreConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*CommitStoreConfigSet, error) + + FilterConfigSet0(opts *bind.FilterOpts) (*CommitStoreConfigSet0Iterator, error) + + WatchConfigSet0(opts *bind.WatchOpts, sink chan<- *CommitStoreConfigSet0) (event.Subscription, error) + + ParseConfigSet0(log types.Log) (*CommitStoreConfigSet0, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*CommitStoreOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*CommitStoreOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *CommitStoreOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*CommitStoreOwnershipTransferred, error) + + FilterPaused(opts *bind.FilterOpts) (*CommitStorePausedIterator, error) + + WatchPaused(opts *bind.WatchOpts, sink chan<- *CommitStorePaused) (event.Subscription, error) + + ParsePaused(log types.Log) (*CommitStorePaused, error) + + FilterReportAccepted(opts *bind.FilterOpts) (*CommitStoreReportAcceptedIterator, error) + + WatchReportAccepted(opts *bind.WatchOpts, sink chan<- *CommitStoreReportAccepted) (event.Subscription, error) + + ParseReportAccepted(log types.Log) (*CommitStoreReportAccepted, error) + + FilterRootRemoved(opts *bind.FilterOpts) (*CommitStoreRootRemovedIterator, error) + + WatchRootRemoved(opts *bind.WatchOpts, sink chan<- *CommitStoreRootRemoved) (event.Subscription, error) + + ParseRootRemoved(log types.Log) (*CommitStoreRootRemoved, error) + + FilterTransmitted(opts *bind.FilterOpts) (*CommitStoreTransmittedIterator, error) + + WatchTransmitted(opts *bind.WatchOpts, sink chan<- *CommitStoreTransmitted) (event.Subscription, error) + + ParseTransmitted(log types.Log) (*CommitStoreTransmitted, error) + + FilterUnpaused(opts *bind.FilterOpts) (*CommitStoreUnpausedIterator, error) + + WatchUnpaused(opts *bind.WatchOpts, sink chan<- *CommitStoreUnpaused) (event.Subscription, error) + + ParseUnpaused(log types.Log) (*CommitStoreUnpaused, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} \ No newline at end of file diff --git a/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go b/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go index 5b9dbf5985..1a48443edb 100644 --- a/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go +++ b/core/gethwrappers/ccip/generated/commit_store_helper/commit_store_helper.go @@ -52,20 +52,24 @@ type CommitStoreStaticConfig struct { ArmProxy common.Address } -type InternalPriceUpdates struct { - TokenPriceUpdates []InternalTokenPriceUpdate +type InternalGasPriceUpdate struct { DestChainSelector uint64 UsdPerUnitGas *big.Int } +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + type InternalTokenPriceUpdate struct { SourceToken common.Address UsdPerToken *big.Int } var CommitStoreHelperMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":\"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\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"bytes\",\"name\":\"commitReport\",\"type\":\"bytes\"},{\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"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\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b5060405162003830380380620038308339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e0516101005161012051613499620003976000396000818161027801528181610555015281816111a1015281816119c801528181611a89015261202d01526000818161023c015261200601526000818161020c0152611fdf0152600081816101dc0152611fb001526000818161131c0152611368015260006113e301526134996000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80637437ff9f116100ee578063a7206cd611610097578063b1dc65a411610071578063b1dc65a414610505578063f2fde38b14610518578063f47a86901461052b578063ff888fb11461053e57600080fd5b8063a7206cd6146104b2578063ad7a22f8146104d2578063afcb95d7146104e557600080fd5b80638456cb59116100c85780638456cb591461047a5780638da5cb5b146104825780638db94e44146104aa57600080fd5b80637437ff9f1461040357806379ba50971461044257806381ff70481461044a57600080fd5b806329b980e4116101505780634120fccd1161012a5780634120fccd146103c05780635c975abb146103d2578063666cab8d146103ee57600080fd5b806329b980e41461038457806332048875146103975780633f4ba83a146103b857600080fd5b8063181f5a7711610181578063181f5a77146103135780631dc18e561461035c5780631ef381741461037157600080fd5b806306285c69146101a85780630a6cd30d146102cb57806310c374ed146102e3575b600080fd5b6102b560408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102c29190612688565b60405180910390f35b6102d3610551565b60405190151581526020016102c2565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102c2565b61034f6040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102c29190612745565b61036f61036a3660046127bb565b6105e8565b005b61036f61037f366004612a4a565b6105f8565b61036f610392366004612b17565b610e19565b6103aa6103a5366004612b77565b610e65565b6040519081526020016102c2565b61036f610f5b565b60095467ffffffffffffffff166102fa565b6009546d0100000000000000000000000000900460ff166102d3565b6103f6610fc1565b6040516102c29190612c3c565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102c2565b61036f611030565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102c2565b61036f61112d565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102c2565b6102d361119d565b6103aa6104c0366004612c4f565b6000908152600a602052604090205490565b61036f6104e0366004612c68565b611254565b6040805160018152600060208201819052918101919091526060016102c2565b61036f610513366004612c83565b611297565b61036f610526366004612d3a565b6118b7565b61036f610539366004612d57565b6118cb565b6102d361054c366004612c4f565b611965565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e29190612d99565b15905090565b6105f3838383611a39565b505050565b855185518560ff16601f831115610670576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106da576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610667565b818314610768576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610667565b610773816003612dea565b83116107db576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610667565b6107e3611e4f565b6107ec86611ed2565b60065460005b818110156108e857600560006006838154811061081157610811612e01565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061088157610881612e01565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108e181612e30565b90506107f2565b50895160005b81811015610cc15760008c828151811061090a5761090a612e01565b602002602001015190506000600281111561092757610927612e68565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561096657610966612e68565b146109cd576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610a1a576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610aca57610aca612e68565b021790555090505060008c8381518110610ae657610ae6612e01565b6020026020010151905060006002811115610b0357610b03612e68565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b4257610b42612e68565b14610ba9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610bf6576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ca657610ca6612e68565b0217905550905050505080610cba90612e30565b90506108ee565b508a51610cd59060069060208e01906125ca565b508951610ce99060079060208d01906125ca565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d6f914691309190600090610d419063ffffffff16612e97565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e61208e565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610e0399989796959493929190612eba565b60405180910390a1505050505050505050505050565b610e21611e4f565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610eb6576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f2787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250612139915050565b9050610f3281611965565b610f40576000915050610f52565b6000908152600a602052604090205490505b95945050505050565b610f63611e4f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b6060600780548060200260200160405190810160405280929190818152602001828054801561102657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ffb575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610667565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611135611e4f565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610fb7565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122e9190612d99565b15801561124f57506009546d0100000000000000000000000000900460ff16155b905090565b61125c611e4f565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6112a6878760208b0135611a39565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146113195780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610667565b467f00000000000000000000000000000000000000000000000000000000000000001461139a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610667565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561143c5760028260200151836040015161141d9190612f50565b6114279190612f69565b611432906001612f50565b60ff169050611452565b602082015161144c906001612f50565b60ff1690505b86811461148b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8685146114c4576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561150757611507612e68565b600281111561151857611518612e68565b905250905060028160200151600281111561153557611535612e68565b14801561157c57506007816000015160ff168154811061155757611557612e01565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6115b2576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006115c0866020612dea565b6115cb896020612dea565b6115d78c610144612fb2565b6115e19190612fb2565b6115eb9190612fb2565b905036811461162f576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610667565b5060008a8a604051611642929190612fc5565b604051908190038120611659918e90602001612fd5565b604051602081830303815290604052805190602001209050611679612654565b8860005b818110156118a65760006001858a846020811061169c5761169c612e01565b6116a991901a601b612f50565b8f8f868181106116bb576116bb612e01565b905060200201358e8e878181106116d4576116d4612e01565b9050602002013560405160008152602001604052604051611711949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611733573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff80821686529397509195509293928401916101009091041660028111156117b6576117b6612e68565b60028111156117c7576117c7612e68565b90525090506001816020015160028111156117e4576117e4612e68565b1461181b576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061183257611832612e01565b60200201511561186e576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061188957611889612e01565b911515602090920201525061189f905081612e30565b905061167d565b505050505050505050505050505050565b6118bf611e4f565b6118c88161245a565b50565b6118d3611e4f565b60005b818110156105f35760008383838181106118f2576118f2612e01565b90506020020135905061190481611965565b611954576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061194b9083815260200190565b60405180910390a15b5061195e81612e30565b90506118d6565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a339190612d99565b92915050565b6009546d0100000000000000000000000000900460ff1615611a87576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190612d99565b15611b4d576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b5b83850185613053565b80515151909150151580611b7d575080516020015167ffffffffffffffff1615155b15611cb55760095464ffffffffff80841668010000000000000000909204161015611c7a57600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f98f5be1b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909216916398f5be1b91611c3491600401613272565b600060405180830381600087803b158015611c4e57600080fd5b505af1158015611c62573d6000803e3d6000fd5b505050506040810151611c755750505050565b611cb5565b6040810151611cb5576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611cf0575060208082015190810151905167ffffffffffffffff9182169116115b15611d2d5780602001516040517fbb1ae18d0000000000000000000000000000000000000000000000000000000081526004016106679190613285565b6040810151611d68576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611db1576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611dc49060016132aa565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517fc14f9167b03b9a5725671c8678a54571219bff700e4a3665aef9e096c6a846f890611e419083906132d2565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ed0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610667565b565b600081806020019051810190611ee8919061332e565b805190915073ffffffffffffffffffffffffffffffffffffffff16611f39576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec39161208291849061337a565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a6040516020016120b2999897969594939291906133f7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b825182516000919081830361217a576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610101821180159061218e57506101018111155b6121c4576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82820101610100811115612225576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612252578660008151811061224057612240612e01565b60200260200101519350505050612453565b60008167ffffffffffffffff81111561226d5761226d61280f565b604051908082528060200260200182016040528015612296578160200160208202803683370190505b50905060008080805b858110156123d95760006001821b8b8116036122fa57888510156122e3578c5160018601958e9181106122d4576122d4612e01565b6020026020010151905061231c565b85516001850194879181106122d4576122d4612e01565b8b5160018401938d91811061231157612311612e01565b602002602001015190505b60008986101561234c578d5160018701968f91811061233d5761233d612e01565b6020026020010151905061236e565b865160018601958891811061236357612363612e01565b602002602001015190505b828511156123a8576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123b2828261254f565b8784815181106123c4576123c4612e01565b6020908102919091010152505060010161229f565b5060018503821480156123eb57508683145b80156123f657508581145b61242c576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061244157612441612e01565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610667565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008183106125915760408051600160208083019190915281830185905260608083018790528351808403909101815260809092019092528051910120612453565b60408051600160208083019190915281830186905260608083018690528351808403909101815260809092019092528051910120612453565b828054828255906000526020600020908101928215612644579160200282015b8281111561264457825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125ea565b50612650929150612673565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b808211156126505760008155600101612674565b60808101611a33828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b81811015612707576020818501810151868301820152016126eb565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061245360208301846126e1565b60008083601f84011261276a57600080fd5b50813567ffffffffffffffff81111561278257600080fd5b60208301915083602082850101111561279a57600080fd5b9250929050565b803564ffffffffff811681146127b657600080fd5b919050565b6000806000604084860312156127d057600080fd5b833567ffffffffffffffff8111156127e757600080fd5b6127f386828701612758565b90945092506128069050602085016127a1565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156128615761286161280f565b60405290565b6040516060810167ffffffffffffffff811182821017156128615761286161280f565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156128d1576128d161280f565b604052919050565b600067ffffffffffffffff8211156128f3576128f361280f565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146118c857600080fd5b600082601f83011261293057600080fd5b81356020612945612940836128d9565b61288a565b82815260059290921b8401810191818101908684111561296457600080fd5b8286015b8481101561298857803561297b816128fd565b8352918301918301612968565b509695505050505050565b803560ff811681146127b657600080fd5b600082601f8301126129b557600080fd5b813567ffffffffffffffff8111156129cf576129cf61280f565b612a0060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8401160161288a565b818152846020838601011115612a1557600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127b657600080fd5b60008060008060008060c08789031215612a6357600080fd5b863567ffffffffffffffff80821115612a7b57600080fd5b612a878a838b0161291f565b97506020890135915080821115612a9d57600080fd5b612aa98a838b0161291f565b9650612ab760408a01612993565b95506060890135915080821115612acd57600080fd5b612ad98a838b016129a4565b9450612ae760808a01612a32565b935060a0890135915080821115612afd57600080fd5b50612b0a89828a016129a4565b9150509295509295509295565b600060208284031215612b2957600080fd5b612453826127a1565b60008083601f840112612b4457600080fd5b50813567ffffffffffffffff811115612b5c57600080fd5b6020830191508360208260051b850101111561279a57600080fd5b600080600080600060608688031215612b8f57600080fd5b853567ffffffffffffffff80821115612ba757600080fd5b612bb389838a01612b32565b90975095506020880135915080821115612bcc57600080fd5b50612bd988828901612b32565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612c3157815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612bff565b509495945050505050565b6020815260006124536020830184612beb565b600060208284031215612c6157600080fd5b5035919050565b600060208284031215612c7a57600080fd5b61245382612a32565b60008060008060008060008060e0898b031215612c9f57600080fd5b606089018a811115612cb057600080fd5b8998503567ffffffffffffffff80821115612cca57600080fd5b612cd68c838d01612758565b909950975060808b0135915080821115612cef57600080fd5b612cfb8c838d01612b32565b909750955060a08b0135915080821115612d1457600080fd5b50612d218b828c01612b32565b999c989b50969995989497949560c00135949350505050565b600060208284031215612d4c57600080fd5b8135612453816128fd565b60008060208385031215612d6a57600080fd5b823567ffffffffffffffff811115612d8157600080fd5b612d8d85828601612b32565b90969095509350505050565b600060208284031215612dab57600080fd5b8151801515811461245357600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a3357611a33612dbb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e6157612e61612dbb565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612eb057612eb0612dbb565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612eea8184018a612beb565b90508281036080840152612efe8189612beb565b905060ff871660a084015282810360c0840152612f1b81876126e1565b905067ffffffffffffffff851660e0840152828103610100840152612f4081856126e1565b9c9b505050505050505050505050565b60ff8181168382160190811115611a3357611a33612dbb565b600060ff831680612fa3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a3357611a33612dbb565b8183823760009101908152919050565b828152606082602083013760800192915050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127b657600080fd5b60006040828403121561302757600080fd5b61302f61283e565b905061303a82612a32565b815261304860208301612a32565b602082015292915050565b6000602080838503121561306657600080fd5b823567ffffffffffffffff8082111561307e57600080fd5b908401906080828703121561309257600080fd5b61309a612867565b8235828111156130a957600080fd5b8301606081890312156130bb57600080fd5b6130c3612867565b8135848111156130d257600080fd5b82019350601f840189136130e557600080fd5b83356130f3612940826128d9565b81815260069190911b8501870190878101908b83111561311257600080fd5b958801955b82871015613166576040878d0312156131305760008081fd5b61313861283e565b8735613143816128fd565b8152613150888b01612fe9565b818b015282526040969096019590880190613117565b8352506131769050828701612a32565b8682015261318660408301612fe9565b604082015282525061319a87848601613015565b93810193909352506060013560408201529392505050565b805160608084528151908401819052600091602091908201906080860190845b8181101561322d578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685840152928401926040909201916001016131d2565b505067ffffffffffffffff83860151168387015260408501519250610f5260408701847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169052565b60208152600061245360208301846131b2565b60408101611a338284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff8181168382160190808211156132cb576132cb612dbb565b5092915050565b6020815260008251608060208401526132ee60a08401826131b2565b905060208401516133196040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b60006020828403121561334057600080fd5b6040516020810181811067ffffffffffffffff821117156133635761336361280f565b6040528251613371816128fd565b81529392505050565b60a081016133d3828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b16604085015281606085015261343e8285018b612beb565b91508382036080850152613452828a612beb565b915060ff881660a085015283820360c085015261346f82886126e1565b90861660e08501528381036101008501529050612f4081856126e156fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitStoreConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"}],\"name\":\"InvalidInterval\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LeavesCannotBeEmpty\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NonUniqueSignatures\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PausedError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootAlreadyCommitted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SignaturesOutOfRegistration\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleReport\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedSigner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongNumberOfSignatures\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":\"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\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"min\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"max\",\"type\":\"uint64\"}],\"internalType\":\"structCommitStore.Interval\",\"name\":\"interval\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"merkleRoot\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structCommitStore.CommitReport\",\"name\":\"report\",\"type\":\"tuple\"}],\"name\":\"ReportAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"RootRemoved\",\"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\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLatestPriceEpochAndRound\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"getMerkleRoot\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structCommitStore.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"name\":\"isBlessed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"isUnpausedAndARMHealthy\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDetails\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"configCount\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestConfigDigestAndEpoch\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"scanLogs\",\"type\":\"bool\"},{\"internalType\":\"bytes32\",\"name\":\"configDigest\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"epoch\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"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\":\"bytes\",\"name\":\"commitReport\",\"type\":\"bytes\"},{\"internalType\":\"uint40\",\"name\":\"epochAndRound\",\"type\":\"uint40\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"rootToReset\",\"type\":\"bytes32[]\"}],\"name\":\"resetUnblessedRoots\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint40\",\"name\":\"latestPriceEpochAndRound\",\"type\":\"uint40\"}],\"name\":\"setLatestPriceEpochAndRound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"minSeqNr\",\"type\":\"uint64\"}],\"name\":\"setMinSeqNr\",\"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\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[3]\",\"name\":\"reportContext\",\"type\":\"bytes32[3]\"},{\"internalType\":\"bytes\",\"name\":\"report\",\"type\":\"bytes\"},{\"internalType\":\"bytes32[]\",\"name\":\"rs\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"ss\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32\",\"name\":\"rawVs\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"hashedLeaves\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"name\":\"verify\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x61014060405260098054600165ff000000000160401b03191660011790553480156200002a57600080fd5b50604051620038e8380380620038e88339810160408190526200004d9162000274565b80600033808281620000a65760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d957620000d98162000194565b50505015156080524660a05260408101516001600160a01b0316158062000108575080516001600160401b0316155b806200011f575060208101516001600160401b0316155b8062000136575060608101516001600160a01b0316155b156200015557604051631fc5f15f60e11b815260040160405180910390fd5b80516001600160401b0390811660c05260208201511660e05260408101516001600160a01b039081166101005260609091015116610120525062000308565b336001600160a01b03821603620001ee5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160401b03811681146200025757600080fd5b919050565b80516001600160a01b03811681146200025757600080fd5b6000608082840312156200028757600080fd5b604051608081016001600160401b0381118282101715620002b857634e487b7160e01b600052604160045260246000fd5b604052620002c6836200023f565b8152620002d6602084016200023f565b6020820152620002e9604084016200025c565b6040820152620002fc606084016200025c565b60608201529392505050565b60805160a05160c05160e0516101005161012051613551620003976000396000818161027801528181610555015281816111a1015281816119c801528181611a89015261202401526000818161023c0152611ffd01526000818161020c0152611fd60152600081816101dc0152611fa701526000818161131c0152611368015260006113e301526135516000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c80637437ff9f116100ee578063a7206cd611610097578063b1dc65a411610071578063b1dc65a414610505578063f2fde38b14610518578063f47a86901461052b578063ff888fb11461053e57600080fd5b8063a7206cd6146104b2578063ad7a22f8146104d2578063afcb95d7146104e557600080fd5b80638456cb59116100c85780638456cb591461047a5780638da5cb5b146104825780638db94e44146104aa57600080fd5b80637437ff9f1461040357806379ba50971461044257806381ff70481461044a57600080fd5b806329b980e4116101505780634120fccd1161012a5780634120fccd146103c05780635c975abb146103d2578063666cab8d146103ee57600080fd5b806329b980e41461038457806332048875146103975780633f4ba83a146103b857600080fd5b8063181f5a7711610181578063181f5a77146103135780631dc18e561461035c5780631ef381741461037157600080fd5b806306285c69146101a85780630a6cd30d146102cb57806310c374ed146102e3575b600080fd5b6102b560408051608081018252600080825260208201819052918101829052606081019190915260405180608001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516102c2919061267f565b60405180910390f35b6102d3610551565b60405190151581526020016102c2565b60095468010000000000000000900464ffffffffff165b60405167ffffffffffffffff90911681526020016102c2565b61034f6040518060400160405280601181526020017f436f6d6d697453746f726520312e322e3000000000000000000000000000000081525081565b6040516102c2919061273c565b61036f61036a3660046127b2565b6105e8565b005b61036f61037f366004612a41565b6105f8565b61036f610392366004612b0e565b610e19565b6103aa6103a5366004612b6e565b610e65565b6040519081526020016102c2565b61036f610f5b565b60095467ffffffffffffffff166102fa565b6009546d0100000000000000000000000000900460ff166102d3565b6103f6610fc1565b6040516102c29190612c33565b604080516020808201835260009091528151808201835260085473ffffffffffffffffffffffffffffffffffffffff16908190529151918252016102c2565b61036f611030565b6004546002546040805163ffffffff808516825264010000000090940490931660208401528201526060016102c2565b61036f61112d565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102c2565b6102d361119d565b6103aa6104c0366004612c46565b6000908152600a602052604090205490565b61036f6104e0366004612c5f565b611254565b6040805160018152600060208201819052918101919091526060016102c2565b61036f610513366004612c7a565b611297565b61036f610526366004612d31565b6118b7565b61036f610539366004612d4e565b6118cb565b6102d361054c366004612c46565b611965565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105e29190612d90565b15905090565b6105f3838383611a39565b505050565b855185518560ff16601f831115610670576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f746f6f206d616e79207369676e6572730000000000000000000000000000000060448201526064015b60405180910390fd5b806000036106da576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f73697469766500000000000000000000000000006044820152606401610667565b818314610768576040517f89a61989000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f7261636c6520616464726573736573206f7574206f6620726567697374726160448201527f74696f6e000000000000000000000000000000000000000000000000000000006064820152608401610667565b610773816003612de1565b83116107db576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f6661756c74792d6f7261636c65206620746f6f206869676800000000000000006044820152606401610667565b6107e3611e46565b6107ec86611ec9565b60065460005b818110156108e857600560006006838154811061081157610811612df8565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556007805460059291908490811061088157610881612df8565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108e181612e27565b90506107f2565b50895160005b81811015610cc15760008c828151811061090a5761090a612df8565b602002602001015190506000600281111561092757610927612e5f565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff16600281111561096657610966612e5f565b146109cd576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265706561746564207369676e657220616464726573730000000000000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610a1a576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016001905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610aca57610aca612e5f565b021790555090505060008c8381518110610ae657610ae6612df8565b6020026020010151905060006002811115610b0357610b03612e5f565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260056020526040902054610100900460ff166002811115610b4257610b42612e5f565b14610ba9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d69747465722061646472657373000000006044820152606401610667565b73ffffffffffffffffffffffffffffffffffffffff8116610bf6576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff84168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526005602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ca657610ca6612e5f565b0217905550905050505080610cba90612e27565b90506108ee565b508a51610cd59060069060208e01906125c1565b508951610ce99060079060208d01906125c1565b506003805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908c161717905560048054610d6f914691309190600090610d419063ffffffff16612e8e565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168e8e8e8e8e8e612085565b600260000181905550600060048054906101000a900463ffffffff169050436004806101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600260000154600460009054906101000a900463ffffffff168f8f8f8f8f8f604051610e0399989796959493929190612eb1565b60405180910390a1505050505050505050505050565b610e21611e46565b6009805464ffffffffff90921668010000000000000000027fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff909216919091179055565b6009546000906d0100000000000000000000000000900460ff1615610eb6576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f2787878080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808b0282810182019093528a82529093508a925089918291850190849080828437600092019190915250889250612130915050565b9050610f3281611965565b610f40576000915050610f52565b6000908152600a602052604090205490505b95945050505050565b610f63611e46565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff1690556040513381527f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906020015b60405180910390a1565b6060600780548060200260200160405190810160405280929190818152602001828054801561102657602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ffb575b5050505050905090565b60015473ffffffffffffffffffffffffffffffffffffffff1633146110b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610667565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611135611e46565b600980547fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff166d01000000000000000000000000001790556040513381527f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25890602001610fb7565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122e9190612d90565b15801561124f57506009546d0100000000000000000000000000900460ff16155b905090565b61125c611e46565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff92909216919091179055565b6112a6878760208b0135611a39565b6040805160608101825260025480825260035460ff8082166020850152610100909104169282019290925289359182146113195780516040517f93df584c000000000000000000000000000000000000000000000000000000008152600481019190915260248101839052604401610667565b467f00000000000000000000000000000000000000000000000000000000000000001461139a576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604401610667565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a160007f00000000000000000000000000000000000000000000000000000000000000001561143c5760028260200151836040015161141d9190612f47565b6114279190612f60565b611432906001612f47565b60ff169050611452565b602082015161144c906001612f47565b60ff1690505b86811461148b576040517f71253a2500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8685146114c4576040517fa75d88af00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526005602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561150757611507612e5f565b600281111561151857611518612e5f565b905250905060028160200151600281111561153557611535612e5f565b14801561157c57506007816000015160ff168154811061155757611557612df8565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b6115b2576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006115c0866020612de1565b6115cb896020612de1565b6115d78c610144612fa9565b6115e19190612fa9565b6115eb9190612fa9565b905036811461162f576040517f8e1192e100000000000000000000000000000000000000000000000000000000815260048101829052366024820152604401610667565b5060008a8a604051611642929190612fbc565b604051908190038120611659918e90602001612fcc565b60405160208183030381529060405280519060200120905061167961264b565b8860005b818110156118a65760006001858a846020811061169c5761169c612df8565b6116a991901a601b612f47565b8f8f868181106116bb576116bb612df8565b905060200201358e8e878181106116d4576116d4612df8565b9050602002013560405160008152602001604052604051611711949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015611733573d6000803e3d6000fd5b5050604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081015173ffffffffffffffffffffffffffffffffffffffff8116600090815260056020908152848220848601909552845460ff80821686529397509195509293928401916101009091041660028111156117b6576117b6612e5f565b60028111156117c7576117c7612e5f565b90525090506001816020015160028111156117e4576117e4612e5f565b1461181b576040517fca31867a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051859060ff16601f811061183257611832612df8565b60200201511561186e576040517ff67bc7c400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600185826000015160ff16601f811061188957611889612df8565b911515602090920201525061189f905081612e27565b905061167d565b505050505050505050505050505050565b6118bf611e46565b6118c881612451565b50565b6118d3611e46565b60005b818110156105f35760008383838181106118f2576118f2612df8565b90506020020135905061190481611965565b611954576000818152600a602052604080822091909155517f202f1139a3e334b6056064c0e9b19fd07e44a88d8f6e5ded571b24cf8c371f129061194b9083815260200190565b60405180910390a15b5061195e81612e27565b90506118d6565b6040805180820182523081526020810183815291517f4d616771000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9081166004830152915160248201526000917f00000000000000000000000000000000000000000000000000000000000000001690634d61677190604401602060405180830381865afa158015611a0f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a339190612d90565b92915050565b6009546d0100000000000000000000000000900460ff1615611a87576040517feced32bc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611af2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b169190612d90565b15611b4d576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000611b5b838501856130d7565b80515151909150151580611b7457508051602001515115155b15611cac5760095464ffffffffff80841668010000000000000000909204161015611c7157600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff166801000000000000000064ffffffffff85160217905560085481516040517f3937306f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90921691633937306f91611c2b9160040161332a565b600060405180830381600087803b158015611c4557600080fd5b505af1158015611c59573d6000803e3d6000fd5b505050506040810151611c6c5750505050565b611cac565b6040810151611cac576040517ff803a2ca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208101515160095467ffffffffffffffff9081169116141580611ce7575060208082015190810151905167ffffffffffffffff9182169116115b15611d245780602001516040517fbb1ae18d000000000000000000000000000000000000000000000000000000008152600401610667919061333d565b6040810151611d5f576040517f504570e300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040808201516000908152600a602052205415611da8576040517fa0bce24f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808201510151611dbb906001613362565b600980547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790556040818101516000908152600a602052819020429055517f291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf590611e3890839061338a565b60405180910390a150505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611ec7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610667565b565b600081806020019051810190611edf91906133e6565b805190915073ffffffffffffffffffffffffffffffffffffffff16611f30576040517f3f8be2be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff928316179055600980547fffffffffffffffffffffffffffffffffffffff0000000000ffffffffffffffff169055604080516080810182527f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff90811682527f00000000000000000000000000000000000000000000000000000000000000001660208201527f00000000000000000000000000000000000000000000000000000000000000008316818301527f00000000000000000000000000000000000000000000000000000000000000009092166060830152517fc9d7123efd4203e60b0f0a4b1dbc4800fc97ce63679f71c3a27279b24a7ddec391612079918490613432565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a6040516020016120a9999897969594939291906134af565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b8251825160009190818303612171576040517f11a6b26400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610101821180159061218557506101018111155b6121bb576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8282010161010081111561221c576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003612249578660008151811061223757612237612df8565b6020026020010151935050505061244a565b60008167ffffffffffffffff81111561226457612264612806565b60405190808252806020026020018201604052801561228d578160200160208202803683370190505b50905060008080805b858110156123d05760006001821b8b8116036122f157888510156122da578c5160018601958e9181106122cb576122cb612df8565b60200260200101519050612313565b85516001850194879181106122cb576122cb612df8565b8b5160018401938d91811061230857612308612df8565b602002602001015190505b600089861015612343578d5160018701968f91811061233457612334612df8565b60200260200101519050612365565b865160018601958891811061235a5761235a612df8565b602002602001015190505b8285111561239f576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123a98282612546565b8784815181106123bb576123bb612df8565b60209081029190910101525050600101612296565b5060018503821480156123e257508683145b80156123ed57508581145b612423576040517f09bde33900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600186038151811061243857612438612df8565b60200260200101519750505050505050505b9392505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036124d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610667565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000818310612588576040805160016020808301919091528183018590526060808301879052835180840390910181526080909201909252805191012061244a565b6040805160016020808301919091528183018690526060808301869052835180840390910181526080909201909252805191012061244a565b82805482825590600052602060002090810192821561263b579160200282015b8281111561263b57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906125e1565b5061264792915061266a565b5090565b604051806103e00160405280601f906020820280368337509192915050565b5b80821115612647576000815560010161266b565b60808101611a33828467ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b6000815180845260005b818110156126fe576020818501810151868301820152016126e2565b5060006020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b60208152600061244a60208301846126d8565b60008083601f84011261276157600080fd5b50813567ffffffffffffffff81111561277957600080fd5b60208301915083602082850101111561279157600080fd5b9250929050565b803564ffffffffff811681146127ad57600080fd5b919050565b6000806000604084860312156127c757600080fd5b833567ffffffffffffffff8111156127de57600080fd5b6127ea8682870161274f565b90945092506127fd905060208501612798565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561285857612858612806565b60405290565b6040516060810167ffffffffffffffff8111828210171561285857612858612806565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156128c8576128c8612806565b604052919050565b600067ffffffffffffffff8211156128ea576128ea612806565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff811681146118c857600080fd5b600082601f83011261292757600080fd5b8135602061293c612937836128d0565b612881565b82815260059290921b8401810191818101908684111561295b57600080fd5b8286015b8481101561297f578035612972816128f4565b835291830191830161295f565b509695505050505050565b803560ff811681146127ad57600080fd5b600082601f8301126129ac57600080fd5b813567ffffffffffffffff8111156129c6576129c6612806565b6129f760207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601612881565b818152846020838601011115612a0c57600080fd5b816020850160208301376000918101602001919091529392505050565b803567ffffffffffffffff811681146127ad57600080fd5b60008060008060008060c08789031215612a5a57600080fd5b863567ffffffffffffffff80821115612a7257600080fd5b612a7e8a838b01612916565b97506020890135915080821115612a9457600080fd5b612aa08a838b01612916565b9650612aae60408a0161298a565b95506060890135915080821115612ac457600080fd5b612ad08a838b0161299b565b9450612ade60808a01612a29565b935060a0890135915080821115612af457600080fd5b50612b0189828a0161299b565b9150509295509295509295565b600060208284031215612b2057600080fd5b61244a82612798565b60008083601f840112612b3b57600080fd5b50813567ffffffffffffffff811115612b5357600080fd5b6020830191508360208260051b850101111561279157600080fd5b600080600080600060608688031215612b8657600080fd5b853567ffffffffffffffff80821115612b9e57600080fd5b612baa89838a01612b29565b90975095506020880135915080821115612bc357600080fd5b50612bd088828901612b29565b96999598509660400135949350505050565b600081518084526020808501945080840160005b83811015612c2857815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101612bf6565b509495945050505050565b60208152600061244a6020830184612be2565b600060208284031215612c5857600080fd5b5035919050565b600060208284031215612c7157600080fd5b61244a82612a29565b60008060008060008060008060e0898b031215612c9657600080fd5b606089018a811115612ca757600080fd5b8998503567ffffffffffffffff80821115612cc157600080fd5b612ccd8c838d0161274f565b909950975060808b0135915080821115612ce657600080fd5b612cf28c838d01612b29565b909750955060a08b0135915080821115612d0b57600080fd5b50612d188b828c01612b29565b999c989b50969995989497949560c00135949350505050565b600060208284031215612d4357600080fd5b813561244a816128f4565b60008060208385031215612d6157600080fd5b823567ffffffffffffffff811115612d7857600080fd5b612d8485828601612b29565b90969095509350505050565b600060208284031215612da257600080fd5b8151801515811461244a57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082028115828204841417611a3357611a33612db2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e5857612e58612db2565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600063ffffffff808316818103612ea757612ea7612db2565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152612ee18184018a612be2565b90508281036080840152612ef58189612be2565b905060ff871660a084015282810360c0840152612f1281876126d8565b905067ffffffffffffffff851660e0840152828103610100840152612f3781856126d8565b9c9b505050505050505050505050565b60ff8181168382160190811115611a3357611a33612db2565b600060ff831680612f9a577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b8060ff84160491505092915050565b80820180821115611a3357611a33612db2565b8183823760009101908152919050565b828152606082602083013760800192915050565b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146127ad57600080fd5b600082601f83011261301d57600080fd5b8135602061302d612937836128d0565b82815260069290921b8401810191818101908684111561304c57600080fd5b8286015b8481101561297f57604081890312156130695760008081fd5b613071612835565b61307a82612a29565b8152613087858301612fe0565b81860152835291830191604001613050565b6000604082840312156130ab57600080fd5b6130b3612835565b90506130be82612a29565b81526130cc60208301612a29565b602082015292915050565b600060208083850312156130ea57600080fd5b823567ffffffffffffffff8082111561310257600080fd5b908401906080828703121561311657600080fd5b61311e61285e565b82358281111561312d57600080fd5b8301604081890381131561314057600080fd5b613148612835565b82358581111561315757600080fd5b8301601f81018b1361316857600080fd5b8035613176612937826128d0565b81815260069190911b8201890190898101908d83111561319557600080fd5b928a01925b828410156131e55785848f0312156131b25760008081fd5b6131ba612835565b84356131c5816128f4565b81526131d2858d01612fe0565b818d0152825292850192908a019061319a565b845250505082870135858111156131fb57600080fd5b6132078b82860161300c565b8289015250835261321a89868801613099565b8684015260608501358184015250508094505050505092915050565b805160408084528151848201819052600092602091908201906060870190855b818110156132af578351805173ffffffffffffffffffffffffffffffffffffffff1684528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858401529284019291850191600101613256565b50508583015187820388850152805180835290840192506000918401905b8083101561331e578351805167ffffffffffffffff1683528501517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16858301529284019260019290920191908501906132cd565b50979650505050505050565b60208152600061244a6020830184613236565b60408101611a338284805167ffffffffffffffff908116835260209182015116910152565b67ffffffffffffffff81811683821601908082111561338357613383612db2565b5092915050565b6020815260008251608060208401526133a660a0840182613236565b905060208401516133d16040850182805167ffffffffffffffff908116835260209182015116910152565b50604084015160808401528091505092915050565b6000602082840312156133f857600080fd5b6040516020810181811067ffffffffffffffff8211171561341b5761341b612806565b6040528251613429816128f4565b81529392505050565b60a0810161348b828567ffffffffffffffff80825116835280602083015116602084015250604081015173ffffffffffffffffffffffffffffffffffffffff808216604085015280606084015116606085015250505050565b73ffffffffffffffffffffffffffffffffffffffff83511660808301529392505050565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526134f68285018b612be2565b9150838203608085015261350a828a612be2565b915060ff881660a085015283820360c085015261352782886126d8565b90861660e08501528381036101008501529050612f3781856126d856fea164736f6c6343000813000a", } var CommitStoreHelperABI = CommitStoreHelperMetaData.ABI @@ -1831,7 +1835,7 @@ func (CommitStoreHelperPaused) Topic() common.Hash { } func (CommitStoreHelperReportAccepted) Topic() common.Hash { - return common.HexToHash("0xc14f9167b03b9a5725671c8678a54571219bff700e4a3665aef9e096c6a846f8") + return common.HexToHash("0x291698c01aa71f912280535d88a00d2c59fb63530a3f5d0098560468acb9ebf5") } func (CommitStoreHelperRootRemoved) Topic() common.Hash { diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go index d3c376ed23..6ebe5c6f92 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp/evm_2_evm_offramp.go @@ -104,7 +104,7 @@ type RateLimiterTokenBucket struct { var EVM2EVMOffRampMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"contractIPool[]\",\"name\":\"pools\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenRateLimitError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"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\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"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\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getDestinationToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDestinationTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"getPoolByDestToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"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\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"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\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"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\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101806040523480156200001257600080fd5b5060405162006aae38038062006aae833981016040819052620000359162000891565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c08162000478565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080938401819052600380546001600160a01b031916909517600160801b9384021760ff60a01b1916600160a01b90920291909117909355909102909217600455504690528151835114620001705760405162d8548360e71b815260040160405180910390fd5b60608401516001600160a01b0316158062000193575083516001600160a01b0316155b15620001b2576040516342bcdf7f60e11b815260040160405180910390fd5b83600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021b9190620009a8565b6001600160401b03166001146200024557604051636fc2a20760e11b815260040160405180910390fd5b83516001600160a01b0390811660a090815260408601516001600160401b0390811660c05260208701511660e052606086015182166101005260808601518216610140528501511661016052620002bc7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000523565b6101205260005b83518110156200046d576200031d848281518110620002e657620002e6620009c6565b6020026020010151848381518110620003035762000303620009c6565b6020026020010151600c6200058a60201b9092919060201c565b50620003d2838281518110620003375762000337620009c6565b60200260200101516001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200037d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a39190620009dc565b848381518110620003b857620003b8620009c6565b6020026020010151600f6200058a60201b9092919060201c565b507f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c848281518110620004095762000409620009c6565b6020026020010151848381518110620004265762000426620009c6565b6020026020010151604051620004529291906001600160a01b0392831681529116602082015260400190565b60405180910390a1620004658162000a03565b9050620002c3565b505050505062000a2b565b336001600160a01b03821603620004d25760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e051610100516040516020016200056d94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000620005a2846001600160a01b03851684620005aa565b949350505050565b6000620005a284846001600160a01b03851660008281526002840160205260408120829055620005a284846000620005e38383620005ec565b90505b92915050565b60008181526001830160205260408120546200063557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005e6565b506000620005e6565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156200067957620006796200063e565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006aa57620006aa6200063e565b604052919050565b6001600160a01b0381168114620006c857600080fd5b50565b80516001600160401b0381168114620006e357600080fd5b919050565b60006001600160401b038211156200070457620007046200063e565b5060051b60200190565b600082601f8301126200072057600080fd5b81516020620007396200073383620006e8565b6200067f565b82815260059290921b840181019181810190868411156200075957600080fd5b8286015b84811015620007815780516200077381620006b2565b83529183019183016200075d565b509695505050505050565b600082601f8301126200079e57600080fd5b81516020620007b16200073383620006e8565b82815260059290921b84018101918181019086841115620007d157600080fd5b8286015b8481101562000781578051620007eb81620006b2565b8352918301918301620007d5565b80516001600160801b0381168114620006e357600080fd5b6000606082840312156200082457600080fd5b604051606081016001600160401b03811182821017156200084957620008496200063e565b8060405250809150825180151581146200086257600080fd5b81526200087260208401620007f9565b60208201526200088560408401620007f9565b60408201525092915050565b600080600080848603610160811215620008aa57600080fd5b60c0811215620008b957600080fd5b50620008c462000654565b8551620008d181620006b2565b8152620008e160208701620006cb565b6020820152620008f460408701620006cb565b604082015260608601516200090981620006b2565b606082015260808601516200091e81620006b2565b608082015260a08601516200093381620006b2565b60a082015260c08601519094506001600160401b03808211156200095657600080fd5b62000964888389016200070e565b945060e08701519150808211156200097b57600080fd5b506200098a878288016200078c565b9250506200099d86610100870162000811565b905092959194509250565b600060208284031215620009bb57600080fd5b620005e382620006cb565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009ef57600080fd5b8151620009fc81620006b2565b9392505050565b60006001820162000a2457634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c05160e05161010051610120516101405161016051615fa662000b0860003960008181610309015281816120fd015261239b0152600081816102cd01528181611622015281816116a4015281816120d30152818161291101526129980152600061255401526000818161029101526120ac015260008181610231015261205a015260008181610261015281816120840152818161312401526138100152600081816101f50152818161202c015261264901526000818161136b015281816113b70152818161176501526117b10152615fa66000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806379ba5097116100ee578063b1dc65a411610097578063d3c7c2c711610071578063d3c7c2c7146106a7578063d7e2bb50146106af578063f2fde38b146106c2578063f52121a5146106d557600080fd5b8063b1dc65a41461066e578063b4069b3114610681578063c92b28321461069457600080fd5b8063856c8247116100c8578063856c8247146106045780638da5cb5b14610630578063afcb95d71461064e57600080fd5b806379ba5097146105be57806381ff7048146105c657806385572ffb146105f657600080fd5b8063599f64311161015b578063681fba1611610135578063681fba16146104b8578063704b6c02146104cd578063740f4150146104e05780637437ff9f146104f357600080fd5b8063599f6431146104515780635d86f14114610490578063666cab8d146104a357600080fd5b80631ef381741161018c5780631ef38174146103c55780633a87ac53146103da578063546719cd146103ed57600080fd5b806306285c69146101b3578063142a98fc1461035c578063181f5a771461037c575b600080fd5b6103466040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161035391906146b1565b60405180910390f35b61036f61036a366004614748565b6106e8565b60405161035391906147cf565b6103b86040518060400160405280601481526020017f45564d3245564d4f666652616d7020312e322e3000000000000000000000000081525081565b604051610353919061484b565b6103d86103d3366004614ab9565b610763565b005b6103d86103e8366004614bcb565b610c22565b6103f5611032565b604051610353919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610353565b61046b61049e366004614c37565b6110e7565b6104ab611150565b6040516103539190614ca5565b6104c06111bf565b6040516103539190614cb8565b6103d86104db366004614c37565b611278565b6103d86104ee366004615151565b611368565b6105b16040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff808216835273ffffffffffffffffffffffffffffffffffffffff64010000000090920482166020840152600b549182169383019390935261ffff7401000000000000000000000000000000000000000082041660608301527601000000000000000000000000000000000000000000009004909116608082015290565b604051610353919061520c565b6103d86114ea565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610353565b6103d86101ae36600461526f565b610617610612366004614c37565b6115e7565b60405167ffffffffffffffff9091168152602001610353565b60005473ffffffffffffffffffffffffffffffffffffffff1661046b565b604080516001815260006020820181905291810191909152606001610353565b6103d861067c3660046152ef565b61170f565b61046b61068f366004614c37565b6119a0565b6103d86106a23660046153f4565b611a79565b6104c0611afe565b61046b6106bd366004614c37565b611bb3565b6103d86106d0366004614c37565b611bc2565b6103d86106e3366004615462565b611bd3565b60006106f6600160046154f5565b6002610703608085615537565b67ffffffffffffffff16610717919061555e565b60136000610726608087615575565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c16600381111561075d5761075d614765565b92915050565b84518460ff16601f8211156107d9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6f206d616e79207472616e736d697474657273000000000000000000000060448201526064015b60405180910390fd5b80600003610843576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f736974697665000000000000000000000000000060448201526064016107d0565b61084b611e2d565b61085485611eb0565b60095460005b818110156108e05760086000600983815481106108795761087961559c565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108d9816155cb565b905061085a565b50875160005b81811015610adc5760008a82815181106109025761090261559c565b602002602001015190506000600281111561091f5761091f614765565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054610100900460ff16600281111561095e5761095e614765565b146109c5576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d697474657220616464726573730000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8116610a12576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ac257610ac2614765565b02179055509050505080610ad5906155cb565b90506108e6565b508851610af09060099060208c019061461b565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908b161717905560078054610b76914691309190600090610b489063ffffffff16615603565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168d8d8d8d8d8d61215d565b6005600001819055506000600760049054906101000a900463ffffffff16905043600760046101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600560000154600760009054906101000a900463ffffffff168e8e8e8e8e8e604051610c0d99989796959493929190615626565b60405180910390a15050505050505050505050565b610c2a611e2d565b60005b83811015610e29576000858583818110610c4957610c4961559c565b610c5f9260206040909202019081019150614c37565b90506000868684818110610c7557610c7561559c565b9050604002016020016020810190610c8d9190614c37565b9050610c9a600c83612208565b610cd0576040517f9c8787c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610cf2600c8461222a565b73ffffffffffffffffffffffffffffffffffffffff1614610d3f576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d4a600c8361224c565b50610dc58173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbd91906156bc565b600f9061224c565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a1505080610e22906155cb565b9050610c2d565b5060005b8181101561102b576000838383818110610e4957610e4961559c565b610e5f9260206040909202019081019150614c37565b90506000848484818110610e7557610e7561559c565b9050604002016020016020810190610e8d9190614c37565b905073ffffffffffffffffffffffffffffffffffffffff82161580610ec6575073ffffffffffffffffffffffffffffffffffffffff8116155b15610efd576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f08600c83612208565b15610f3f576040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f4b600c838361226e565b50610fc78173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbe91906156bc565b600f908361226e565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a1505080611024906155cb565b9050610e2d565b5050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff1615159383019390935260045480841660608401520490911660808201526110e290612291565b905090565b600080806110f6600c85612343565b9150915081611149576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016107d0565b9392505050565b606060098054806020026020016040519081016040528092919081815260200182805480156111b557602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161118a575b5050505050905090565b60606111cb600f612372565b67ffffffffffffffff8111156111e3576111e361485e565b60405190808252806020026020018201604052801561120c578160200160208202803683370190505b50905060005b8151811015611274576000611228600f8361237d565b5090508083838151811061123e5761123e61559c565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101525061126d816155cb565b9050611212565b5090565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906112b8575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156112ef576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b467f0000000000000000000000000000000000000000000000000000000000000000146113f3576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015267ffffffffffffffff461660248201526044016107d0565b81515181518114611430576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156114da57600083828151811061144f5761144f61559c565b6020026020010151905080600014158015611488575084518051839081106114795761147961559c565b60200260200101516080015181105b156114c9576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016107d0565b506114d3816155cb565b9050611433565b506114e58383612399565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461156b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107d0565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff811660009081526012602052604081205467ffffffffffffffff168015801561165a57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b1561075d576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa1580156116eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114991906156d9565b6117198787612d49565b600554883590808214611762576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016107d0565b467f0000000000000000000000000000000000000000000000000000000000000000146117e3576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107d0565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561186b5761186b614765565b600281111561187c5761187c614765565b905250905060028160200151600281111561189957611899614765565b1480156118e057506009816000015160ff16815481106118bb576118bb61559c565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611916576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600061192485602061555e565b61192f88602061555e565b61193b8b6101446156f6565b61194591906156f6565b61194f91906156f6565b9050368114611993576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107d0565b5050505050505050505050565b600080806119af600c85612343565b9150915081611a02576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016107d0565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a7191906156bc565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611ab9575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15611af0576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611afb600382612d70565b50565b6060611b0a600c612372565b67ffffffffffffffff811115611b2257611b2261485e565b604051908082528060200260200182016040528015611b4b578160200160208202803683370190505b50905060005b8151811015611274576000611b67600c8361237d565b50905080838381518110611b7d57611b7d61559c565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250611bac816155cb565b9050611b51565b600080806110f6600f85612343565b611bca611e2d565b611afb81612f55565b333014611c0c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611c49565b6040805180820190915260008082526020820152815260200190600190039081611c225790505b506101408401515190915015611cb657611cb38361014001518460200151604051602001611c93919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405160208183030381529060405285604001518661016001518661304a565b90505b604083015173ffffffffffffffffffffffffffffffffffffffff163b1580611d2057506040830151611d1e9073ffffffffffffffffffffffffffffffffffffffff167f85572ffb0000000000000000000000000000000000000000000000000000000061352d565b155b15611d2a57505050565b600a546000908190640100000000900473ffffffffffffffffffffffffffffffffffffffff16633cf97983611d5f8786613549565b611388886080015189604001516040518563ffffffff1660e01b8152600401611d8b949392919061575a565b6000604051808303816000875af1158015611daa573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611df0919081019061582c565b915091508161102b57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107d0919061484b565b60005473ffffffffffffffffffffffffffffffffffffffff163314611eae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107d0565b565b600081806020019051810190611ec691906158cd565b602081015190915073ffffffffffffffffffffffffffffffffffffffff16611f1a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090931663ffffffff9586161792909217909255604080850151600b80546060808901516080808b0151909916760100000000000000000000000000000000000000000000027fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff61ffff90921674010000000000000000000000000000000000000000027fffffffffffffffffffff00000000000000000000000000000000000000000000909416958816959095179290921791909116929092179055815160c0810183527f00000000000000000000000000000000000000000000000000000000000000008416815267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116958201959095527f0000000000000000000000000000000000000000000000000000000000000000909416848301527f00000000000000000000000000000000000000000000000000000000000000008316908401527f00000000000000000000000000000000000000000000000000000000000000008216938301939093527f00000000000000000000000000000000000000000000000000000000000000001660a082015290517f737ef22d3f6615e342ed21c69e06620dbc5c8a261ed7cfb2ce214806b1f76eda91612151918490615968565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a60405160200161218199989796959493929190615a37565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b60006111498373ffffffffffffffffffffffffffffffffffffffff84166135f9565b60006111498373ffffffffffffffffffffffffffffffffffffffff8416613605565b60006111498373ffffffffffffffffffffffffffffffffffffffff8416613611565b6000611a718473ffffffffffffffffffffffffffffffffffffffff85168461361d565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261231f82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261230391906154f5565b85608001516fffffffffffffffffffffffffffffffff16613640565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6000806123668473ffffffffffffffffffffffffffffffffffffffff851661365f565b915091505b9250929050565b600061075d8261366e565b600080808061238c8686613679565b9097909650945050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124289190615acc565b1561245f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815151600081900361249c576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82602001515181146124da576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156124f5576124f561485e565b60405190808252806020026020018201604052801561251e578160200160208202803683370190505b50905060005b828110156125fe576000856000015182815181106125445761254461559c565b60200260200101519050612578817f0000000000000000000000000000000000000000000000000000000000000000613688565b83838151811061258a5761258a61559c565b6020026020010181815250508061018001518383815181106125ae576125ae61559c565b6020026020010151146125ed576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506125f7816155cb565b9050612524565b50604080850151606086015191517f3204887500000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263320488759261267f92879291600401615b19565b602060405180830381865afa15801561269c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c09190615b4f565b9050806000036126fc576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b84811015612d40576000876000015182815181106127235761272361559c565b60200260200101519050600061273c82606001516106e8565b9050600081600381111561275257612752614765565b148061276f5750600381600381111561276d5761276d614765565b145b6127b75760608201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b831561287457600a5460009063ffffffff166127d387426154f5565b11905080806127f3575060038260038111156127f1576127f1614765565b145b612829576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88848151811061283b5761283b61559c565b602002602001015160001461286e5788848151811061285c5761285c61559c565b60200260200101518360800181815250505b506128d1565b600081600381111561288857612888614765565b146128d15760608201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b60208083015173ffffffffffffffffffffffffffffffffffffffff1660009081526012909152604090205467ffffffffffffffff168015801561294957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b15612aec5760208301516040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156129e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0591906156d9565b60c084015190915067ffffffffffffffff16612a22826001615b68565b67ffffffffffffffff1614612a8f57826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a3505050612d30565b60208381015173ffffffffffffffffffffffffffffffffffffffff16600090815260129091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b6000826003811115612b0057612b00614765565b03612b8c5760c083015167ffffffffffffffff16612b1f826001615b68565b67ffffffffffffffff1614612b8c57826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a3505050612d30565b60008a602001518581518110612ba457612ba461559c565b60200260200101519050612bb984825161380e565b612bc8846060015160016139e4565b600080612bd58684613a8e565b91509150612be78660600151836139e4565b6003826003811115612bfb57612bfb614765565b14158015612c1b57506002826003811115612c1857612c18614765565b14155b15612c5a578560600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016107d0929190615b89565b6000856003811115612c6e57612c6e614765565b03612cdb5760208087015173ffffffffffffffffffffffffffffffffffffffff166000908152601290915260408120805467ffffffffffffffff1691612cb383615ba7565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef658484604051612d21929190615bc4565b60405180910390a35050505050505b612d39816155cb565b9050612703565b50505050505050565b612d6c612d5882840184615be4565b604080516000815260208101909152612399565b5050565b8154600090612d9990700100000000000000000000000000000000900463ffffffff16426154f5565b90508015612e3b5760018301548354612de1916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416613640565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e61916fffffffffffffffffffffffffffffffff9081169116613c31565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612f489084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b3373ffffffffffffffffffffffffffffffffffffffff821603612fd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107d0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60606000865167ffffffffffffffff8111156130685761306861485e565b6040519080825280602002602001820160405280156130ad57816020015b60408051808201909152600080825260208201528152602001906001900390816130865790505b50905060005b87518110156134fc5760006130e48983815181106130d3576130d361559c565b6020026020010151600001516110e7565b90508073ffffffffffffffffffffffffffffffffffffffff16638627fad689898c86815181106131165761311661559c565b6020026020010151602001517f00000000000000000000000000000000000000000000000000000000000000008b88815181106131555761315561559c565b60200260200101518b898151811061316f5761316f61559c565b6020026020010151604051602001613188929190615c19565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016131b7959493929190615c3e565b600060405180830381600087803b1580156131d157600080fd5b505af19250505080156131e2575060015b613405573d808015613210576040519150601f19603f3d011682016040523d82523d6000602084013e613215565b606091505b50600061322182615ca1565b90507f9725942a000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000821614806132b457507ff94ebcd1000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b8061330057507f15279c08000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b8061334c57507f1a76572a000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b8061339857507fd0c8d23a000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b156133d157816040517f30dabb590000000000000000000000000000000000000000000000000000000081526004016107d0919061484b565b816040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107d0919061484b565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015613450573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347491906156bc565b8383815181106134865761348661559c565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff909116905288518990839081106134bf576134bf61559c565b6020026020010151602001518383815181106134dd576134dd61559c565b6020908102919091018101510152506134f5816155cb565b90506130b3565b50600b5461352190829073ffffffffffffffffffffffffffffffffffffffff16613c47565b90505b95945050505050565b600061353883613e2f565b801561114957506111498383613e93565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff16815260200184602001516040516020016135ce919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b60006111498383613f62565b60006111498383613f6e565b60006111498383613ff8565b6000611a71848473ffffffffffffffffffffffffffffffffffffffff8516614015565b600061352485613650848661555e565b61365a90876156f6565b613c31565b600080808061238c8686614032565b600061075d8261406c565b600080808061238c8686614077565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b610100015160405160200161372b98979695949392919073ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b60405160208183030381529060405280519060200120856101200151805190602001208661014001516040516020016137649190615cf1565b604051602081830303815290604052805190602001208761016001516040516020016137909190615d59565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16826000015167ffffffffffffffff161461388e5781516040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b600b54610140830151517401000000000000000000000000000000000000000090910461ffff1610156138ff5760608201516040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b8082610140015151146139505760608201516040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b600b546101208301515176010000000000000000000000000000000000000000000090910463ffffffff161015612d6c57600b54610120830151516040517f8693378900000000000000000000000000000000000000000000000000000000815276010000000000000000000000000000000000000000000090920463ffffffff16600483015260248201526044016107d0565b600060026139f3608085615537565b67ffffffffffffffff16613a07919061555e565b90506000601381613a19608087615575565b67ffffffffffffffff168152602081019190915260400160002054905081613a43600160046154f5565b901b191681836003811115613a5a57613a5a614765565b901b178060136000613a6d608088615575565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a590613ad29087908790600401615d6c565b600060405180830381600087803b158015613aec57600080fd5b505af1925050508015613afd575060015b613c16573d808015613b2b576040519150601f19603f3d011682016040523d82523d6000602084013e613b30565b606091505b50613b3a81615ca1565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0a8d6e8c000000000000000000000000000000000000000000000000000000001480613bd25750613b8d81615ca1565b7fffffffff00000000000000000000000000000000000000000000000000000000167fe1cd550900000000000000000000000000000000000000000000000000000000145b15613be25760039250905061236b565b806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016107d0919061484b565b50506040805160208101909152600081526002909250929050565b6000818310613c405781611149565b5090919050565b81516000805b82811015613e1b5760008473ffffffffffffffffffffffffffffffffffffffff1663d02641a0878481518110613c8557613c8561559c565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016040805180830381865afa158015613cf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613d1d9190615ef6565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613daf57858281518110613d5857613d5861559c565b6020908102919091010151516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107d0565b613dfd868381518110613dc457613dc461559c565b602002602001015160200151827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166140a290919063ffffffff16565b613e0790846156f6565b92505080613e14906155cb565b9050613c4d565b50613e2960038260006140df565b50505050565b6000613e5b827f01ffc9a700000000000000000000000000000000000000000000000000000000613e93565b801561075d5750613e8c827fffffffff00000000000000000000000000000000000000000000000000000000613e93565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613f4b575060208210155b8015613f575750600081115b979650505050505050565b60006111498383614462565b600081815260028301602052604081205480151580613f925750613f928484613f62565b611149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b6579000060448201526064016107d0565b60008181526002830160205260408120819055611149838361447a565b60008281526002840160205260408120829055611a718484614486565b6000818152600283016020526040812054819080614061576140548585613f62565b92506000915061236b9050565b60019250905061236b565b600061075d82614492565b60008080614085858561449c565b600081815260029690960160205260409095205494959350505050565b6000670de0b6b3a76400006140d5837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661555e565b6111499190615f56565b825474010000000000000000000000000000000000000000900460ff161580614106575081155b1561411057505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061415690700100000000000000000000000000000000900463ffffffff16426154f5565b905080156142165781831115614198576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546141d29083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16613640565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156142cd5773ffffffffffffffffffffffffffffffffffffffff8416614275576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016107d0565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016107d0565b848310156143e05760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061431190826154f5565b61431b878a6154f5565b61432591906156f6565b61432f9190615f56565b905073ffffffffffffffffffffffffffffffffffffffff8616614388576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107d0565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016107d0565b6143ea85846154f5565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60008181526001830160205260408120541515611149565b600061114983836144a8565b600061114983836145a2565b600061075d825490565b600061114983836145f1565b600081815260018301602052604081205480156145915760006144cc6001836154f5565b85549091506000906144e0906001906154f5565b90508181146145455760008660000182815481106145005761450061559c565b90600052602060002001549050808760000184815481106145235761452361559c565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061455657614556615f6a565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061075d565b600091505061075d565b5092915050565b60008181526001830160205260408120546145e95750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561075d565b50600061075d565b60008260000182815481106146085761460861559c565b9060005260206000200154905092915050565b828054828255906000526020600020908101928215614695579160200282015b8281111561469557825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90911617825560209092019160019091019061463b565b506112749291505b80821115611274576000815560010161469d565b60c0810161075d828473ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b67ffffffffffffffff81168114611afb57600080fd5b803561474381614722565b919050565b60006020828403121561475a57600080fd5b813561114981614722565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600481106147cb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6020810161075d8284614794565b60005b838110156147f85781810151838201526020016147e0565b50506000910152565b600081518084526148198160208601602086016147dd565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111496020830184614801565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156148b0576148b061485e565b60405290565b6040516101a0810167ffffffffffffffff811182821017156148b0576148b061485e565b6040516080810167ffffffffffffffff811182821017156148b0576148b061485e565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156149445761494461485e565b604052919050565b600067ffffffffffffffff8211156149665761496661485e565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611afb57600080fd5b803561474381614970565b600082601f8301126149ae57600080fd5b813560206149c36149be8361494c565b6148fd565b82815260059290921b840181019181810190868411156149e257600080fd5b8286015b84811015614a065780356149f981614970565b83529183019183016149e6565b509695505050505050565b803560ff8116811461474357600080fd5b600067ffffffffffffffff821115614a3c57614a3c61485e565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112614a7957600080fd5b8135614a876149be82614a22565b818152846020838601011115614a9c57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614ad257600080fd5b863567ffffffffffffffff80821115614aea57600080fd5b614af68a838b0161499d565b97506020890135915080821115614b0c57600080fd5b614b188a838b0161499d565b9650614b2660408a01614a11565b95506060890135915080821115614b3c57600080fd5b614b488a838b01614a68565b9450614b5660808a01614738565b935060a0890135915080821115614b6c57600080fd5b50614b7989828a01614a68565b9150509295509295509295565b60008083601f840112614b9857600080fd5b50813567ffffffffffffffff811115614bb057600080fd5b6020830191508360208260061b850101111561236b57600080fd5b60008060008060408587031215614be157600080fd5b843567ffffffffffffffff80821115614bf957600080fd5b614c0588838901614b86565b90965094506020870135915080821115614c1e57600080fd5b50614c2b87828801614b86565b95989497509550505050565b600060208284031215614c4957600080fd5b813561114981614970565b600081518084526020808501945080840160005b83811015614c9a57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614c68565b509495945050505050565b6020815260006111496020830184614c54565b6020808252825182820181905260009190848201906040850190845b81811015614d0657835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614cd4565b50909695505050505050565b8015158114611afb57600080fd5b803561474381614d12565b600082601f830112614d3c57600080fd5b81356020614d4c6149be8361494c565b82815260069290921b84018101918181019086841115614d6b57600080fd5b8286015b84811015614a065760408189031215614d885760008081fd5b614d9061488d565b8135614d9b81614970565b81528185013585820152835291830191604001614d6f565b600082601f830112614dc457600080fd5b81356020614dd46149be8361494c565b82815260059290921b84018101918181019086841115614df357600080fd5b8286015b84811015614a0657803567ffffffffffffffff811115614e175760008081fd5b614e258986838b0101614a68565b845250918301918301614df7565b60006101a08284031215614e4657600080fd5b614e4e6148b6565b9050614e5982614738565b8152614e6760208301614992565b6020820152614e7860408301614992565b6040820152614e8960608301614738565b606082015260808201356080820152614ea460a08301614d20565b60a0820152614eb560c08301614738565b60c0820152614ec660e08301614992565b60e082015261010082810135908201526101208083013567ffffffffffffffff80821115614ef357600080fd5b614eff86838701614a68565b83850152610140925082850135915080821115614f1b57600080fd5b614f2786838701614d2b565b83850152610160925082850135915080821115614f4357600080fd5b50614f5085828601614db3565b82840152505061018080830135818301525092915050565b600082601f830112614f7957600080fd5b81356020614f896149be8361494c565b82815260059290921b84018101918181019086841115614fa857600080fd5b8286015b84811015614a0657803567ffffffffffffffff811115614fcc5760008081fd5b614fda8986838b0101614db3565b845250918301918301614fac565b600082601f830112614ff957600080fd5b813560206150096149be8361494c565b82815260059290921b8401810191818101908684111561502857600080fd5b8286015b84811015614a06578035835291830191830161502c565b60006080828403121561505557600080fd5b61505d6148da565b9050813567ffffffffffffffff8082111561507757600080fd5b818401915084601f83011261508b57600080fd5b8135602061509b6149be8361494c565b82815260059290921b840181019181810190888411156150ba57600080fd5b8286015b848110156150f2578035868111156150d65760008081fd5b6150e48b86838b0101614e33565b8452509183019183016150be565b508652508581013593508284111561510957600080fd5b61511587858801614f68565b9085015250604084013591508082111561512e57600080fd5b5061513b84828501614fe8565b6040830152506060820135606082015292915050565b6000806040838503121561516457600080fd5b823567ffffffffffffffff8082111561517c57600080fd5b61518886838701615043565b935060209150818501358181111561519f57600080fd5b85019050601f810186136151b257600080fd5b80356151c06149be8261494c565b81815260059190911b820183019083810190888311156151df57600080fd5b928401925b828410156151fd578335825292840192908401906151e4565b80955050505050509250929050565b60a0810161075d828463ffffffff808251168352602082015173ffffffffffffffffffffffffffffffffffffffff8082166020860152806040850151166040860152505061ffff6060830151166060840152806080830151166080840152505050565b60006020828403121561528157600080fd5b813567ffffffffffffffff81111561529857600080fd5b820160a0818503121561114957600080fd5b60008083601f8401126152bc57600080fd5b50813567ffffffffffffffff8111156152d457600080fd5b6020830191508360208260051b850101111561236b57600080fd5b60008060008060008060008060e0898b03121561530b57600080fd5b606089018a81111561531c57600080fd5b8998503567ffffffffffffffff8082111561533657600080fd5b818b0191508b601f83011261534a57600080fd5b81358181111561535957600080fd5b8c602082850101111561536b57600080fd5b6020830199508098505060808b013591508082111561538957600080fd5b6153958c838d016152aa565b909750955060a08b01359150808211156153ae57600080fd5b506153bb8b828c016152aa565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff8116811461474357600080fd5b60006060828403121561540657600080fd5b6040516060810181811067ffffffffffffffff821117156154295761542961485e565b604052823561543781614d12565b8152615445602084016153d4565b6020820152615456604084016153d4565b60408201529392505050565b6000806040838503121561547557600080fd5b823567ffffffffffffffff8082111561548d57600080fd5b61549986838701614e33565b935060208501359150808211156154af57600080fd5b506154bc85828601614db3565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561075d5761075d6154c6565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061555257615552615508565b92169190910692915050565b808202811582820484141761075d5761075d6154c6565b600067ffffffffffffffff8084168061559057615590615508565b92169190910492915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036155fc576155fc6154c6565b5060010190565b600063ffffffff80831681810361561c5761561c6154c6565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526156568184018a614c54565b9050828103608084015261566a8189614c54565b905060ff871660a084015282810360c08401526156878187614801565b905067ffffffffffffffff851660e08401528281036101008401526156ac8185614801565b9c9b505050505050505050505050565b6000602082840312156156ce57600080fd5b815161114981614970565b6000602082840312156156eb57600080fd5b815161114981614722565b8082018082111561075d5761075d6154c6565b600081518084526020808501945080840160005b83811015614c9a578151805173ffffffffffffffffffffffffffffffffffffffff168852830151838801526040909601959082019060010161571d565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152615795610120840182614801565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e08601526157d18383614801565b9250608089015191508085840301610100860152506157f08282615709565b92505050615804602083018661ffff169052565b836040830152613524606083018473ffffffffffffffffffffffffffffffffffffffff169052565b6000806040838503121561583f57600080fd5b825161584a81614d12565b602084015190925067ffffffffffffffff81111561586757600080fd5b8301601f8101851361587857600080fd5b80516158866149be82614a22565b81815286602083850101111561589b57600080fd5b6158ac8260208301602086016147dd565b8093505050509250929050565b805163ffffffff8116811461474357600080fd5b600060a082840312156158df57600080fd5b60405160a0810181811067ffffffffffffffff821117156159025761590261485e565b60405261590e836158b9565b8152602083015161591e81614970565b6020820152604083015161593181614970565b6040820152606083015161ffff8116811461594b57600080fd5b606082015261595c608084016158b9565b60808201529392505050565b61016081016159da828573ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b825163ffffffff90811660c0840152602084015173ffffffffffffffffffffffffffffffffffffffff90811660e0850152604085015116610100840152606084015161ffff16610120840152608084015116610140830152611149565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152615a7e8285018b614c54565b91508382036080850152615a92828a614c54565b915060ff881660a085015283820360c0850152615aaf8288614801565b90861660e085015283810361010085015290506156ac8185614801565b600060208284031215615ade57600080fd5b815161114981614d12565b600081518084526020808501945080840160005b83811015614c9a57815187529582019590820190600101615afd565b606081526000615b2c6060830186615ae9565b8281036020840152615b3e8186615ae9565b915050826040830152949350505050565b600060208284031215615b6157600080fd5b5051919050565b67ffffffffffffffff81811683821601908082111561459b5761459b6154c6565b67ffffffffffffffff83168152604081016111496020830184614794565b600067ffffffffffffffff80831681810361561c5761561c6154c6565b615bce8184614794565b604060208201526000611a716040830184614801565b600060208284031215615bf657600080fd5b813567ffffffffffffffff811115615c0d57600080fd5b611a7184828501615043565b604081526000615c2c6040830185614801565b82810360208401526135248185614801565b60a081526000615c5160a0830188614801565b73ffffffffffffffffffffffffffffffffffffffff8716602084015285604084015267ffffffffffffffff851660608401528281036080840152615c958185614801565b98975050505050505050565b6000815160208301517fffffffff0000000000000000000000000000000000000000000000000000000080821693506004831015615ce95780818460040360031b1b83161693505b505050919050565b6020815260006111496020830184615709565b600081518084526020808501808196508360051b8101915082860160005b85811015615d4c578284038952615d3a848351614801565b98850198935090840190600101615d22565b5091979650505050505050565b6020815260006111496020830184615d04565b60408152615d8760408201845167ffffffffffffffff169052565b60006020840151615db0606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604084015173ffffffffffffffffffffffffffffffffffffffff8116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615e1e8185018367ffffffffffffffff169052565b60e08601519150610120615e498186018473ffffffffffffffffffffffffffffffffffffffff169052565b81870151925061014091508282860152808701519250506101a06101608181870152615e796101e0870185614801565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0610180818887030181890152615eb88686615709565b9550828a01519450818887030184890152615ed38686615d04565b9550808a01516101c0890152505050505082810360208401526135248185615d04565b600060408284031215615f0857600080fd5b615f1061488d565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615f3c57600080fd5b8152615f4a602084016158b9565b60208201529392505050565b600082615f6557615f65615508565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", + Bin: "0x6101806040523480156200001257600080fd5b50604051620068f3380380620068f3833981016040819052620000359162000891565b8033806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c08162000478565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080938401819052600380546001600160a01b031916909517600160801b9384021760ff60a01b1916600160a01b90920291909117909355909102909217600455504690528151835114620001705760405162d8548360e71b815260040160405180910390fd5b60608401516001600160a01b0316158062000193575083516001600160a01b0316155b15620001b2576040516342bcdf7f60e11b815260040160405180910390fd5b83600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200021b9190620009a8565b6001600160401b03166001146200024557604051636fc2a20760e11b815260040160405180910390fd5b83516001600160a01b0390811660a090815260408601516001600160401b0390811660c05260208701511660e052606086015182166101005260808601518216610140528501511661016052620002bc7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000523565b6101205260005b83518110156200046d576200031d848281518110620002e657620002e6620009c6565b6020026020010151848381518110620003035762000303620009c6565b6020026020010151600c6200058a60201b9092919060201c565b50620003d2838281518110620003375762000337620009c6565b60200260200101516001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200037d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003a39190620009dc565b848381518110620003b857620003b8620009c6565b6020026020010151600f6200058a60201b9092919060201c565b507f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c848281518110620004095762000409620009c6565b6020026020010151848381518110620004265762000426620009c6565b6020026020010151604051620004529291906001600160a01b0392831681529116602082015260400190565b60405180910390a1620004658162000a03565b9050620002c3565b505050505062000a2b565b336001600160a01b03821603620004d25760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e051610100516040516020016200056d94939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000620005a2846001600160a01b03851684620005aa565b949350505050565b6000620005a284846001600160a01b03851660008281526002840160205260408120829055620005a284846000620005e38383620005ec565b90505b92915050565b60008181526001830160205260408120546200063557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005e6565b506000620005e6565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156200067957620006796200063e565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006aa57620006aa6200063e565b604052919050565b6001600160a01b0381168114620006c857600080fd5b50565b80516001600160401b0381168114620006e357600080fd5b919050565b60006001600160401b038211156200070457620007046200063e565b5060051b60200190565b600082601f8301126200072057600080fd5b81516020620007396200073383620006e8565b6200067f565b82815260059290921b840181019181810190868411156200075957600080fd5b8286015b84811015620007815780516200077381620006b2565b83529183019183016200075d565b509695505050505050565b600082601f8301126200079e57600080fd5b81516020620007b16200073383620006e8565b82815260059290921b84018101918181019086841115620007d157600080fd5b8286015b8481101562000781578051620007eb81620006b2565b8352918301918301620007d5565b80516001600160801b0381168114620006e357600080fd5b6000606082840312156200082457600080fd5b604051606081016001600160401b03811182821017156200084957620008496200063e565b8060405250809150825180151581146200086257600080fd5b81526200087260208401620007f9565b60208201526200088560408401620007f9565b60408201525092915050565b600080600080848603610160811215620008aa57600080fd5b60c0811215620008b957600080fd5b50620008c462000654565b8551620008d181620006b2565b8152620008e160208701620006cb565b6020820152620008f460408701620006cb565b604082015260608601516200090981620006b2565b606082015260808601516200091e81620006b2565b608082015260a08601516200093381620006b2565b60a082015260c08601519094506001600160401b03808211156200095657600080fd5b62000964888389016200070e565b945060e08701519150808211156200097b57600080fd5b506200098a878288016200078c565b9250506200099d86610100870162000811565b905092959194509250565b600060208284031215620009bb57600080fd5b620005e382620006cb565b634e487b7160e01b600052603260045260246000fd5b600060208284031215620009ef57600080fd5b8151620009fc81620006b2565b9392505050565b60006001820162000a2457634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c05160e05161010051610120516101405161016051615deb62000b0860003960008181610309015281816120fd015261239b0152600081816102cd01528181611622015281816116a4015281816120d30152818161291101526129980152600061255401526000818161029101526120ac015260008181610231015261205a015260008181610261015281816120840152818161312401526136550152600081816101f50152818161202c015261264901526000818161136b015281816113b70152818161176501526117b10152615deb6000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806379ba5097116100ee578063b1dc65a411610097578063d3c7c2c711610071578063d3c7c2c7146106a7578063d7e2bb50146106af578063f2fde38b146106c2578063f52121a5146106d557600080fd5b8063b1dc65a41461066e578063b4069b3114610681578063c92b28321461069457600080fd5b8063856c8247116100c8578063856c8247146106045780638da5cb5b14610630578063afcb95d71461064e57600080fd5b806379ba5097146105be57806381ff7048146105c657806385572ffb146105f657600080fd5b8063599f64311161015b578063681fba1611610135578063681fba16146104b8578063704b6c02146104cd578063740f4150146104e05780637437ff9f146104f357600080fd5b8063599f6431146104515780635d86f14114610490578063666cab8d146104a357600080fd5b80631ef381741161018c5780631ef38174146103c55780633a87ac53146103da578063546719cd146103ed57600080fd5b806306285c69146101b3578063142a98fc1461035c578063181f5a771461037c575b600080fd5b6103466040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b60405161035391906144f6565b60405180910390f35b61036f61036a36600461458d565b6106e8565b6040516103539190614614565b6103b86040518060400160405280601481526020017f45564d3245564d4f666652616d7020312e322e3000000000000000000000000081525081565b6040516103539190614690565b6103d86103d33660046148fe565b610763565b005b6103d86103e8366004614a10565b610c22565b6103f5611032565b604051610353919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610353565b61046b61049e366004614a7c565b6110e7565b6104ab611150565b6040516103539190614aea565b6104c06111bf565b6040516103539190614afd565b6103d86104db366004614a7c565b611278565b6103d86104ee366004614f96565b611368565b6105b16040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff808216835273ffffffffffffffffffffffffffffffffffffffff64010000000090920482166020840152600b549182169383019390935261ffff7401000000000000000000000000000000000000000082041660608301527601000000000000000000000000000000000000000000009004909116608082015290565b6040516103539190615051565b6103d86114ea565b6007546005546040805163ffffffff80851682526401000000009094049093166020840152820152606001610353565b6103d86101ae3660046150b4565b610617610612366004614a7c565b6115e7565b60405167ffffffffffffffff9091168152602001610353565b60005473ffffffffffffffffffffffffffffffffffffffff1661046b565b604080516001815260006020820181905291810191909152606001610353565b6103d861067c366004615134565b61170f565b61046b61068f366004614a7c565b6119a0565b6103d86106a2366004615239565b611a79565b6104c0611afe565b61046b6106bd366004614a7c565b611bb3565b6103d86106d0366004614a7c565b611bc2565b6103d86106e33660046152a7565b611bd3565b60006106f66001600461533a565b600261070360808561537c565b67ffffffffffffffff1661071791906153a3565b601360006107266080876153ba565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c16600381111561075d5761075d6145aa565b92915050565b84518460ff16601f8211156107d9576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6f206d616e79207472616e736d697474657273000000000000000000000060448201526064015b60405180910390fd5b80600003610843576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f736974697665000000000000000000000000000060448201526064016107d0565b61084b611e2d565b61085485611eb0565b60095460005b818110156108e0576008600060098381548110610879576108796153e1565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001690556108d981615410565b905061085a565b50875160005b81811015610adc5760008a8281518110610902576109026153e1565b602002602001015190506000600281111561091f5761091f6145aa565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054610100900460ff16600281111561095e5761095e6145aa565b146109c5576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d697474657220616464726573730000000060448201526064016107d0565b73ffffffffffffffffffffffffffffffffffffffff8116610a12576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610ac257610ac26145aa565b02179055509050505080610ad590615410565b90506108e6565b508851610af09060099060208c0190614460565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908b161717905560078054610b76914691309190600090610b489063ffffffff16615448565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168d8d8d8d8d8d61215d565b6005600001819055506000600760049054906101000a900463ffffffff16905043600760046101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600560000154600760009054906101000a900463ffffffff168e8e8e8e8e8e604051610c0d9998979695949392919061546b565b60405180910390a15050505050505050505050565b610c2a611e2d565b60005b83811015610e29576000858583818110610c4957610c496153e1565b610c5f9260206040909202019081019150614a7c565b90506000868684818110610c7557610c756153e1565b9050604002016020016020810190610c8d9190614a7c565b9050610c9a600c83612208565b610cd0576040517f9c8787c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610cf2600c8461222a565b73ffffffffffffffffffffffffffffffffffffffff1614610d3f576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d4a600c8361224c565b50610dc58173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dbd9190615501565b600f9061224c565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a1505080610e2290615410565b9050610c2d565b5060005b8181101561102b576000838383818110610e4957610e496153e1565b610e5f9260206040909202019081019150614a7c565b90506000848484818110610e7557610e756153e1565b9050604002016020016020810190610e8d9190614a7c565b905073ffffffffffffffffffffffffffffffffffffffff82161580610ec6575073ffffffffffffffffffffffffffffffffffffffff8116155b15610efd576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f08600c83612208565b15610f3f576040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f4b600c838361226e565b50610fc78173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbe9190615501565b600f908361226e565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a150508061102490615410565b9050610e2d565b5050505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff1615159383019390935260045480841660608401520490911660808201526110e290612291565b905090565b600080806110f6600c85612343565b9150915081611149576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016107d0565b9392505050565b606060098054806020026020016040519081016040528092919081815260200182805480156111b557602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff16815260019091019060200180831161118a575b5050505050905090565b60606111cb600f612372565b67ffffffffffffffff8111156111e3576111e36146a3565b60405190808252806020026020018201604052801561120c578160200160208202803683370190505b50905060005b8151811015611274576000611228600f8361237d565b5090508083838151811061123e5761123e6153e1565b73ffffffffffffffffffffffffffffffffffffffff909216602092830291909101909101525061126d81615410565b9050611212565b5090565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906112b8575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156112ef576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b467f0000000000000000000000000000000000000000000000000000000000000000146113f3576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015267ffffffffffffffff461660248201526044016107d0565b81515181518114611430576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156114da57600083828151811061144f5761144f6153e1565b602002602001015190508060001415801561148857508451805183908110611479576114796153e1565b60200260200101516080015181105b156114c9576040517f085e39cf00000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016107d0565b506114d381615410565b9050611433565b506114e58383612399565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461156b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016107d0565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff811660009081526012602052604081205467ffffffffffffffff168015801561165a57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b1561075d576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa1580156116eb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611149919061551e565b6117198787612d49565b600554883590808214611762576040517f93df584c00000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016107d0565b467f0000000000000000000000000000000000000000000000000000000000000000146117e3576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201526044016107d0565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff8082168452929391929184019161010090910416600281111561186b5761186b6145aa565b600281111561187c5761187c6145aa565b9052509050600281602001516002811115611899576118996145aa565b1480156118e057506009816000015160ff16815481106118bb576118bb6153e1565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611916576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060006119248560206153a3565b61192f8860206153a3565b61193b8b61014461553b565b611945919061553b565b61194f919061553b565b9050368114611993576040517f8e1192e1000000000000000000000000000000000000000000000000000000008152600481018290523660248201526044016107d0565b5050505050505050505050565b600080806119af600c85612343565b9150915081611a02576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff851660048201526024016107d0565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a4d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a719190615501565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611ab9575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15611af0576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611afb600382612d70565b50565b6060611b0a600c612372565b67ffffffffffffffff811115611b2257611b226146a3565b604051908082528060200260200182016040528015611b4b578160200160208202803683370190505b50905060005b8151811015611274576000611b67600c8361237d565b50905080838381518110611b7d57611b7d6153e1565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250611bac81615410565b9050611b51565b600080806110f6600f85612343565b611bca611e2d565b611afb81612f55565b333014611c0c576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611c49565b6040805180820190915260008082526020820152815260200190600190039081611c225790505b506101408401515190915015611cb657611cb38361014001518460200151604051602001611c93919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b60405160208183030381529060405285604001518661016001518661304a565b90505b604083015173ffffffffffffffffffffffffffffffffffffffff163b1580611d2057506040830151611d1e9073ffffffffffffffffffffffffffffffffffffffff167f85572ffb00000000000000000000000000000000000000000000000000000000613372565b155b15611d2a57505050565b600a546000908190640100000000900473ffffffffffffffffffffffffffffffffffffffff16633cf97983611d5f878661338e565b611388886080015189604001516040518563ffffffff1660e01b8152600401611d8b949392919061559f565b6000604051808303816000875af1158015611daa573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611df09190810190615671565b915091508161102b57806040517f0a8d6e8c0000000000000000000000000000000000000000000000000000000081526004016107d09190614690565b60005473ffffffffffffffffffffffffffffffffffffffff163314611eae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016107d0565b565b600081806020019051810190611ec69190615712565b602081015190915073ffffffffffffffffffffffffffffffffffffffff16611f1a576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090931663ffffffff9586161792909217909255604080850151600b80546060808901516080808b0151909916760100000000000000000000000000000000000000000000027fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff61ffff90921674010000000000000000000000000000000000000000027fffffffffffffffffffff00000000000000000000000000000000000000000000909416958816959095179290921791909116929092179055815160c0810183527f00000000000000000000000000000000000000000000000000000000000000008416815267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116958201959095527f0000000000000000000000000000000000000000000000000000000000000000909416848301527f00000000000000000000000000000000000000000000000000000000000000008316908401527f00000000000000000000000000000000000000000000000000000000000000008216938301939093527f00000000000000000000000000000000000000000000000000000000000000001660a082015290517f737ef22d3f6615e342ed21c69e06620dbc5c8a261ed7cfb2ce214806b1f76eda916121519184906157ad565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a6040516020016121819998979695949392919061587c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b60006111498373ffffffffffffffffffffffffffffffffffffffff841661343e565b60006111498373ffffffffffffffffffffffffffffffffffffffff841661344a565b60006111498373ffffffffffffffffffffffffffffffffffffffff8416613456565b6000611a718473ffffffffffffffffffffffffffffffffffffffff851684613462565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261231f82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642612303919061533a565b85608001516fffffffffffffffffffffffffffffffff16613485565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6000806123668473ffffffffffffffffffffffffffffffffffffffff85166134a4565b915091505b9250929050565b600061075d826134b3565b600080808061238c86866134be565b9097909650945050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124289190615911565b1561245f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815151600081900361249c576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82602001515181146124da576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff8111156124f5576124f56146a3565b60405190808252806020026020018201604052801561251e578160200160208202803683370190505b50905060005b828110156125fe57600085600001518281518110612544576125446153e1565b60200260200101519050612578817f00000000000000000000000000000000000000000000000000000000000000006134cd565b83838151811061258a5761258a6153e1565b6020026020010181815250508061018001518383815181106125ae576125ae6153e1565b6020026020010151146125ed576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506125f781615410565b9050612524565b50604080850151606086015191517f3204887500000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169263320488759261267f9287929160040161595e565b602060405180830381865afa15801561269c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126c09190615994565b9050806000036126fc576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b84811015612d4057600087600001518281518110612723576127236153e1565b60200260200101519050600061273c82606001516106e8565b90506000816003811115612752576127526145aa565b148061276f5750600381600381111561276d5761276d6145aa565b145b6127b75760608201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b831561287457600a5460009063ffffffff166127d3874261533a565b11905080806127f3575060038260038111156127f1576127f16145aa565b145b612829576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88848151811061283b5761283b6153e1565b602002602001015160001461286e5788848151811061285c5761285c6153e1565b60200260200101518360800181815250505b506128d1565b6000816003811115612888576128886145aa565b146128d15760608201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b60208083015173ffffffffffffffffffffffffffffffffffffffff1660009081526012909152604090205467ffffffffffffffff168015801561294957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b15612aec5760208301516040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa1580156129e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a05919061551e565b60c084015190915067ffffffffffffffff16612a228260016159ad565b67ffffffffffffffff1614612a8f57826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a3505050612d30565b60208381015173ffffffffffffffffffffffffffffffffffffffff16600090815260129091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b6000826003811115612b0057612b006145aa565b03612b8c5760c083015167ffffffffffffffff16612b1f8260016159ad565b67ffffffffffffffff1614612b8c57826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a3505050612d30565b60008a602001518581518110612ba457612ba46153e1565b60200260200101519050612bb9848251613653565b612bc884606001516001613829565b600080612bd586846138d3565b91509150612be7866060015183613829565b6003826003811115612bfb57612bfb6145aa565b14158015612c1b57506002826003811115612c1857612c186145aa565b14155b15612c5a578560600151826040517f9e2616030000000000000000000000000000000000000000000000000000000081526004016107d09291906159ce565b6000856003811115612c6e57612c6e6145aa565b03612cdb5760208087015173ffffffffffffffffffffffffffffffffffffffff166000908152601290915260408120805467ffffffffffffffff1691612cb3836159ec565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef658484604051612d21929190615a09565b60405180910390a35050505050505b612d3981615410565b9050612703565b50505050505050565b612d6c612d5882840184615a29565b604080516000815260208101909152612399565b5050565b8154600090612d9990700100000000000000000000000000000000900463ffffffff164261533a565b90508015612e3b5760018301548354612de1916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416613485565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354612e61916fffffffffffffffffffffffffffffffff9081169116613a76565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990612f489084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b3373ffffffffffffffffffffffffffffffffffffffff821603612fd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016107d0565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60606000865167ffffffffffffffff811115613068576130686146a3565b6040519080825280602002602001820160405280156130ad57816020015b60408051808201909152600080825260208201528152602001906001900390816130865790505b50905060005b87518110156133415760006130e48983815181106130d3576130d36153e1565b6020026020010151600001516110e7565b90508073ffffffffffffffffffffffffffffffffffffffff16638627fad689898c8681518110613116576131166153e1565b6020026020010151602001517f00000000000000000000000000000000000000000000000000000000000000008b8881518110613155576131556153e1565b60200260200101518b898151811061316f5761316f6153e1565b6020026020010151604051602001613188929190615a5e565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016131b7959493929190615a83565b600060405180830381600087803b1580156131d157600080fd5b505af19250505080156131e2575060015b61324a573d808015613210576040519150601f19603f3d011682016040523d82523d6000602084013e613215565b606091505b50806040517fe1cd55090000000000000000000000000000000000000000000000000000000081526004016107d09190614690565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015613295573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132b99190615501565b8383815181106132cb576132cb6153e1565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff90911690528851899083908110613304576133046153e1565b602002602001015160200151838381518110613322576133226153e1565b60209081029190910181015101525061333a81615410565b90506130b3565b50600b5461336690829073ffffffffffffffffffffffffffffffffffffffff16613a8c565b90505b95945050505050565b600061337d83613c74565b801561114957506111498383613cd8565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff1681526020018460200151604051602001613413919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b60006111498383613da7565b60006111498383613db3565b60006111498383613e3d565b6000611a71848473ffffffffffffffffffffffffffffffffffffffff8516613e5a565b60006133698561349584866153a3565b61349f908761553b565b613a76565b600080808061238c8686613e77565b600061075d82613eb1565b600080808061238c8686613ebc565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b610100015160405160200161357098979695949392919073ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b60405160208183030381529060405280519060200120856101200151805190602001208661014001516040516020016135a99190615ae6565b604051602081830303815290604052805190602001208761016001516040516020016135d59190615b4e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16826000015167ffffffffffffffff16146136d35781516040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b600b54610140830151517401000000000000000000000000000000000000000090910461ffff1610156137445760608201516040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b8082610140015151146137955760608201516040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016107d0565b600b546101208301515176010000000000000000000000000000000000000000000090910463ffffffff161015612d6c57600b54610120830151516040517f8693378900000000000000000000000000000000000000000000000000000000815276010000000000000000000000000000000000000000000090920463ffffffff16600483015260248201526044016107d0565b6000600261383860808561537c565b67ffffffffffffffff1661384c91906153a3565b9050600060138161385e6080876153ba565b67ffffffffffffffff1681526020810191909152604001600020549050816138886001600461533a565b901b19168183600381111561389f5761389f6145aa565b901b1780601360006138b26080886153ba565b67ffffffffffffffff16815260208101919091526040016000205550505050565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a5906139179087908790600401615b61565b600060405180830381600087803b15801561393157600080fd5b505af1925050508015613942575060015b613a5b573d808015613970576040519150601f19603f3d011682016040523d82523d6000602084013e613975565b606091505b5061397f81615ceb565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0a8d6e8c000000000000000000000000000000000000000000000000000000001480613a1757506139d281615ceb565b7fffffffff00000000000000000000000000000000000000000000000000000000167fe1cd550900000000000000000000000000000000000000000000000000000000145b15613a275760039250905061236b565b806040517fcf19edfd0000000000000000000000000000000000000000000000000000000081526004016107d09190614690565b50506040805160208101909152600081526002909250929050565b6000818310613a855781611149565b5090919050565b81516000805b82811015613c605760008473ffffffffffffffffffffffffffffffffffffffff1663d02641a0878481518110613aca57613aca6153e1565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016040805180830381865afa158015613b3e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b629190615d3b565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613bf457858281518110613b9d57613b9d6153e1565b6020908102919091010151516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016107d0565b613c42868381518110613c0957613c096153e1565b602002602001015160200151827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16613ee790919063ffffffff16565b613c4c908461553b565b92505080613c5990615410565b9050613a92565b50613c6e6003826000613f24565b50505050565b6000613ca0827f01ffc9a700000000000000000000000000000000000000000000000000000000613cd8565b801561075d5750613cd1827fffffffff00000000000000000000000000000000000000000000000000000000613cd8565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015613d90575060208210155b8015613d9c5750600081115b979650505050505050565b600061114983836142a7565b600081815260028301602052604081205480151580613dd75750613dd78484613da7565b611149576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b6579000060448201526064016107d0565b6000818152600283016020526040812081905561114983836142bf565b60008281526002840160205260408120829055611a7184846142cb565b6000818152600283016020526040812054819080613ea657613e998585613da7565b92506000915061236b9050565b60019250905061236b565b600061075d826142d7565b60008080613eca85856142e1565b600081815260029690960160205260409095205494959350505050565b6000670de0b6b3a7640000613f1a837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff86166153a3565b6111499190615d9b565b825474010000000000000000000000000000000000000000900460ff161580613f4b575081155b15613f5557505050565b825460018401546fffffffffffffffffffffffffffffffff80831692911690600090613f9b90700100000000000000000000000000000000900463ffffffff164261533a565b9050801561405b5781831115613fdd576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546140179083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16613485565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156141125773ffffffffffffffffffffffffffffffffffffffff84166140ba576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016107d0565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016107d0565b848310156142255760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16906000908290614156908261533a565b614160878a61533a565b61416a919061553b565b6141749190615d9b565b905073ffffffffffffffffffffffffffffffffffffffff86166141cd576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016107d0565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016107d0565b61422f858461533a565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60008181526001830160205260408120541515611149565b600061114983836142ed565b600061114983836143e7565b600061075d825490565b60006111498383614436565b600081815260018301602052604081205480156143d657600061431160018361533a565b85549091506000906143259060019061533a565b905081811461438a576000866000018281548110614345576143456153e1565b9060005260206000200154905080876000018481548110614368576143686153e1565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061439b5761439b615daf565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061075d565b600091505061075d565b5092915050565b600081815260018301602052604081205461442e5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561075d565b50600061075d565b600082600001828154811061444d5761444d6153e1565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156144da579160200282015b828111156144da57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614480565b506112749291505b8082111561127457600081556001016144e2565b60c0810161075d828473ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b67ffffffffffffffff81168114611afb57600080fd5b803561458881614567565b919050565b60006020828403121561459f57600080fd5b813561114981614567565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614610577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b6020810161075d82846145d9565b60005b8381101561463d578181015183820152602001614625565b50506000910152565b6000815180845261465e816020860160208601614622565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111496020830184614646565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156146f5576146f56146a3565b60405290565b6040516101a0810167ffffffffffffffff811182821017156146f5576146f56146a3565b6040516080810167ffffffffffffffff811182821017156146f5576146f56146a3565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614789576147896146a3565b604052919050565b600067ffffffffffffffff8211156147ab576147ab6146a3565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611afb57600080fd5b8035614588816147b5565b600082601f8301126147f357600080fd5b8135602061480861480383614791565b614742565b82815260059290921b8401810191818101908684111561482757600080fd5b8286015b8481101561484b57803561483e816147b5565b835291830191830161482b565b509695505050505050565b803560ff8116811461458857600080fd5b600067ffffffffffffffff821115614881576148816146a3565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f8301126148be57600080fd5b81356148cc61480382614867565b8181528460208386010111156148e157600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c0878903121561491757600080fd5b863567ffffffffffffffff8082111561492f57600080fd5b61493b8a838b016147e2565b9750602089013591508082111561495157600080fd5b61495d8a838b016147e2565b965061496b60408a01614856565b9550606089013591508082111561498157600080fd5b61498d8a838b016148ad565b945061499b60808a0161457d565b935060a08901359150808211156149b157600080fd5b506149be89828a016148ad565b9150509295509295509295565b60008083601f8401126149dd57600080fd5b50813567ffffffffffffffff8111156149f557600080fd5b6020830191508360208260061b850101111561236b57600080fd5b60008060008060408587031215614a2657600080fd5b843567ffffffffffffffff80821115614a3e57600080fd5b614a4a888389016149cb565b90965094506020870135915080821115614a6357600080fd5b50614a70878288016149cb565b95989497509550505050565b600060208284031215614a8e57600080fd5b8135611149816147b5565b600081518084526020808501945080840160005b83811015614adf57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614aad565b509495945050505050565b6020815260006111496020830184614a99565b6020808252825182820181905260009190848201906040850190845b81811015614b4b57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101614b19565b50909695505050505050565b8015158114611afb57600080fd5b803561458881614b57565b600082601f830112614b8157600080fd5b81356020614b9161480383614791565b82815260069290921b84018101918181019086841115614bb057600080fd5b8286015b8481101561484b5760408189031215614bcd5760008081fd5b614bd56146d2565b8135614be0816147b5565b81528185013585820152835291830191604001614bb4565b600082601f830112614c0957600080fd5b81356020614c1961480383614791565b82815260059290921b84018101918181019086841115614c3857600080fd5b8286015b8481101561484b57803567ffffffffffffffff811115614c5c5760008081fd5b614c6a8986838b01016148ad565b845250918301918301614c3c565b60006101a08284031215614c8b57600080fd5b614c936146fb565b9050614c9e8261457d565b8152614cac602083016147d7565b6020820152614cbd604083016147d7565b6040820152614cce6060830161457d565b606082015260808201356080820152614ce960a08301614b65565b60a0820152614cfa60c0830161457d565b60c0820152614d0b60e083016147d7565b60e082015261010082810135908201526101208083013567ffffffffffffffff80821115614d3857600080fd5b614d44868387016148ad565b83850152610140925082850135915080821115614d6057600080fd5b614d6c86838701614b70565b83850152610160925082850135915080821115614d8857600080fd5b50614d9585828601614bf8565b82840152505061018080830135818301525092915050565b600082601f830112614dbe57600080fd5b81356020614dce61480383614791565b82815260059290921b84018101918181019086841115614ded57600080fd5b8286015b8481101561484b57803567ffffffffffffffff811115614e115760008081fd5b614e1f8986838b0101614bf8565b845250918301918301614df1565b600082601f830112614e3e57600080fd5b81356020614e4e61480383614791565b82815260059290921b84018101918181019086841115614e6d57600080fd5b8286015b8481101561484b5780358352918301918301614e71565b600060808284031215614e9a57600080fd5b614ea261471f565b9050813567ffffffffffffffff80821115614ebc57600080fd5b818401915084601f830112614ed057600080fd5b81356020614ee061480383614791565b82815260059290921b84018101918181019088841115614eff57600080fd5b8286015b84811015614f3757803586811115614f1b5760008081fd5b614f298b86838b0101614c78565b845250918301918301614f03565b5086525085810135935082841115614f4e57600080fd5b614f5a87858801614dad565b90850152506040840135915080821115614f7357600080fd5b50614f8084828501614e2d565b6040830152506060820135606082015292915050565b60008060408385031215614fa957600080fd5b823567ffffffffffffffff80821115614fc157600080fd5b614fcd86838701614e88565b9350602091508185013581811115614fe457600080fd5b85019050601f81018613614ff757600080fd5b803561500561480382614791565b81815260059190911b8201830190838101908883111561502457600080fd5b928401925b8284101561504257833582529284019290840190615029565b80955050505050509250929050565b60a0810161075d828463ffffffff808251168352602082015173ffffffffffffffffffffffffffffffffffffffff8082166020860152806040850151166040860152505061ffff6060830151166060840152806080830151166080840152505050565b6000602082840312156150c657600080fd5b813567ffffffffffffffff8111156150dd57600080fd5b820160a0818503121561114957600080fd5b60008083601f84011261510157600080fd5b50813567ffffffffffffffff81111561511957600080fd5b6020830191508360208260051b850101111561236b57600080fd5b60008060008060008060008060e0898b03121561515057600080fd5b606089018a81111561516157600080fd5b8998503567ffffffffffffffff8082111561517b57600080fd5b818b0191508b601f83011261518f57600080fd5b81358181111561519e57600080fd5b8c60208285010111156151b057600080fd5b6020830199508098505060808b01359150808211156151ce57600080fd5b6151da8c838d016150ef565b909750955060a08b01359150808211156151f357600080fd5b506152008b828c016150ef565b999c989b50969995989497949560c00135949350505050565b80356fffffffffffffffffffffffffffffffff8116811461458857600080fd5b60006060828403121561524b57600080fd5b6040516060810181811067ffffffffffffffff8211171561526e5761526e6146a3565b604052823561527c81614b57565b815261528a60208401615219565b602082015261529b60408401615219565b60408201529392505050565b600080604083850312156152ba57600080fd5b823567ffffffffffffffff808211156152d257600080fd5b6152de86838701614c78565b935060208501359150808211156152f457600080fd5b5061530185828601614bf8565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561075d5761075d61530b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff808416806153975761539761534d565b92169190910692915050565b808202811582820484141761075d5761075d61530b565b600067ffffffffffffffff808416806153d5576153d561534d565b92169190910492915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036154415761544161530b565b5060010190565b600063ffffffff8083168181036154615761546161530b565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b1660408501525080606084015261549b8184018a614a99565b905082810360808401526154af8189614a99565b905060ff871660a084015282810360c08401526154cc8187614646565b905067ffffffffffffffff851660e08401528281036101008401526154f18185614646565b9c9b505050505050505050505050565b60006020828403121561551357600080fd5b8151611149816147b5565b60006020828403121561553057600080fd5b815161114981614567565b8082018082111561075d5761075d61530b565b600081518084526020808501945080840160005b83811015614adf578151805173ffffffffffffffffffffffffffffffffffffffff1688528301518388015260409096019590820190600101615562565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c08401526155da610120840182614646565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e08601526156168383614646565b925060808901519150808584030161010086015250615635828261554e565b92505050615649602083018661ffff169052565b836040830152613369606083018473ffffffffffffffffffffffffffffffffffffffff169052565b6000806040838503121561568457600080fd5b825161568f81614b57565b602084015190925067ffffffffffffffff8111156156ac57600080fd5b8301601f810185136156bd57600080fd5b80516156cb61480382614867565b8181528660208385010111156156e057600080fd5b6156f1826020830160208601614622565b8093505050509250929050565b805163ffffffff8116811461458857600080fd5b600060a0828403121561572457600080fd5b60405160a0810181811067ffffffffffffffff82111715615747576157476146a3565b604052615753836156fe565b81526020830151615763816147b5565b60208201526040830151615776816147b5565b6040820152606083015161ffff8116811461579057600080fd5b60608201526157a1608084016156fe565b60808201529392505050565b610160810161581f828573ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b825163ffffffff90811660c0840152602084015173ffffffffffffffffffffffffffffffffffffffff90811660e0850152604085015116610100840152606084015161ffff16610120840152608084015116610140830152611149565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b1660408501528160608501526158c38285018b614a99565b915083820360808501526158d7828a614a99565b915060ff881660a085015283820360c08501526158f48288614646565b90861660e085015283810361010085015290506154f18185614646565b60006020828403121561592357600080fd5b815161114981614b57565b600081518084526020808501945080840160005b83811015614adf57815187529582019590820190600101615942565b606081526000615971606083018661592e565b8281036020840152615983818661592e565b915050826040830152949350505050565b6000602082840312156159a657600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156143e0576143e061530b565b67ffffffffffffffff831681526040810161114960208301846145d9565b600067ffffffffffffffff8083168181036154615761546161530b565b615a1381846145d9565b604060208201526000611a716040830184614646565b600060208284031215615a3b57600080fd5b813567ffffffffffffffff811115615a5257600080fd5b611a7184828501614e88565b604081526000615a716040830185614646565b82810360208401526133698185614646565b60a081526000615a9660a0830188614646565b73ffffffffffffffffffffffffffffffffffffffff8716602084015285604084015267ffffffffffffffff851660608401528281036080840152615ada8185614646565b98975050505050505050565b602081526000611149602083018461554e565b600081518084526020808501808196508360051b8101915082860160005b85811015615b41578284038952615b2f848351614646565b98850198935090840190600101615b17565b5091979650505050505050565b6020815260006111496020830184615af9565b60408152615b7c60408201845167ffffffffffffffff169052565b60006020840151615ba5606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604084015173ffffffffffffffffffffffffffffffffffffffff8116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615c138185018367ffffffffffffffff169052565b60e08601519150610120615c3e8186018473ffffffffffffffffffffffffffffffffffffffff169052565b81870151925061014091508282860152808701519250506101a06101608181870152615c6e6101e0870185614646565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0610180818887030181890152615cad868661554e565b9550828a01519450818887030184890152615cc88686615af9565b9550808a01516101c0890152505050505082810360208401526133698185615af9565b6000815160208301517fffffffff0000000000000000000000000000000000000000000000000000000080821693506004831015615d335780818460040360031b1b83161693505b505050919050565b600060408284031215615d4d57600080fd5b615d556146d2565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114615d8157600080fd5b8152615d8f602084016156fe565b60208201529392505050565b600082615daa57615daa61534d565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var EVM2EVMOffRampABI = EVM2EVMOffRampMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_offramp_helper/evm_2_evm_offramp_helper.go b/core/gethwrappers/ccip/generated/evm_2_evm_offramp_helper/evm_2_evm_offramp_helper.go index 384c8d34b0..cb6b557723 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_offramp_helper/evm_2_evm_offramp_helper.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_offramp_helper/evm_2_evm_offramp_helper.go @@ -104,7 +104,7 @@ type RateLimiterTokenBucket struct { var EVM2EVMOffRampHelperMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"},{\"internalType\":\"contractIPool[]\",\"name\":\"pools\",\"type\":\"address[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyAttempted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"AlreadyExecuted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CanOnlySelfCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CommitStoreAlreadyInUse\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"expected\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"actual\",\"type\":\"bytes32\"}],\"name\":\"ConfigDigestMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"EmptyReport\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ExecutionError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"ForkedChain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"message\",\"type\":\"string\"}],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"InvalidManualExecutionGasLimit\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMessageId\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"newState\",\"type\":\"uint8\"}],\"name\":\"InvalidNewState\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"}],\"name\":\"InvalidSourceChain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionGasLimitMismatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ManualExecutionNotYetEnabled\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OracleCannotBeZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"ReceiverError\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RootNotCommitted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"TokenDataMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenHandlingError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"error\",\"type\":\"bytes\"}],\"name\":\"TokenRateLimitError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedTransmitter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedTokenData\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"expected\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actual\",\"type\":\"uint256\"}],\"name\":\"WrongMessageLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"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\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"returnData\",\"type\":\"bytes\"}],\"name\":\"ExecutionStateChanged\",\"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\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SkippedSenderWithPreviousRampMessageInflight\",\"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\":\"IS_SCRIPT\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"destTokenAmounts\",\"type\":\"tuple[]\"}],\"internalType\":\"structClient.Any2EVMMessage\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ccipReceive\",\"outputs\":[],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"rep\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"manualExecGasLimits\",\"type\":\"uint256[]\"}],\"name\":\"execute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"executeSingleMessage\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getDestinationToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDestinationTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"destTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"permissionLessExecutionThresholdSeconds\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOffRamp.DynamicConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"}],\"name\":\"getExecutionState\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"bitmapIndex\",\"type\":\"uint64\"}],\"name\":\"getExecutionStateBitMap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"destToken\",\"type\":\"address\"}],\"name\":\"getPoolByDestToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"commitStore\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOffRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"contractIERC20[]\",\"name\":\"sourceTokens\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTransmitters\",\"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\":[{\"components\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage[]\",\"name\":\"messages\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[][]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[][]\"},{\"internalType\":\"bytes32[]\",\"name\":\"proofs\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofFlagBits\",\"type\":\"uint256\"}],\"internalType\":\"structInternal.ExecutionReport\",\"name\":\"report\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"gasLimitOverrides\",\"type\":\"uint256[]\"}],\"name\":\"manuallyExecute\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"metadataHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"sourceTokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"originalSender\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"releaseOrMintTokens\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"executableMessages\",\"type\":\"bytes\"}],\"name\":\"report\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"state\",\"type\":\"uint8\"}],\"name\":\"setExecutionStateHelper\",\"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\":\"setOCR2Config\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"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\":\"\",\"type\":\"bytes32\"}],\"name\":\"transmit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes[]\",\"name\":\"offchainTokenData\",\"type\":\"bytes[]\"}],\"name\":\"trialExecute\",\"outputs\":[{\"internalType\":\"enumInternal.MessageExecutionState\",\"name\":\"\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101806040526014805460ff191660011790553480156200001f57600080fd5b5060405162006f3538038062006f358339810160408190526200004291620008a6565b838383838033806000816200009e5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d157620000d1816200048d565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080938401819052600380546001600160a01b031916909517600160801b9384021760ff60a01b1916600160a01b90920291909117909355909102909217600455504690528151835114620001815760405162d8548360e71b815260040160405180910390fd5b60608401516001600160a01b03161580620001a4575083516001600160a01b0316155b15620001c3576040516342bcdf7f60e11b815260040160405180910390fd5b83600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000206573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022c9190620009bd565b6001600160401b03166001146200025657604051636fc2a20760e11b815260040160405180910390fd5b83516001600160a01b0390811660a090815260408601516001600160401b0390811660c05260208701511660e052606086015182166101005260808601518216610140528501511661016052620002cd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000538565b6101205260005b83518110156200047e576200032e848281518110620002f757620002f7620009db565b6020026020010151848381518110620003145762000314620009db565b6020026020010151600c6200059f60201b9092919060201c565b50620003e3838281518110620003485762000348620009db565b60200260200101516001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200038e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003b49190620009f1565b848381518110620003c957620003c9620009db565b6020026020010151600f6200059f60201b9092919060201c565b507f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c8482815181106200041a576200041a620009db565b6020026020010151848381518110620004375762000437620009db565b6020026020010151604051620004639291906001600160a01b0392831681529116602082015260400190565b60405180910390a1620004768162000a18565b9050620002d4565b50505050505050505062000a40565b336001600160a01b03821603620004e75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000095565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e051610100516040516020016200058294939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000620005b7846001600160a01b03851684620005bf565b949350505050565b6000620005b784846001600160a01b03851660008281526002840160205260408120829055620005b784846000620005f8838362000601565b90505b92915050565b60008181526001830160205260408120546200064a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005fb565b506000620005fb565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156200068e576200068e62000653565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006bf57620006bf62000653565b604052919050565b6001600160a01b0381168114620006dd57600080fd5b50565b80516001600160401b0381168114620006f857600080fd5b919050565b60006001600160401b0382111562000719576200071962000653565b5060051b60200190565b600082601f8301126200073557600080fd5b815160206200074e6200074883620006fd565b62000694565b82815260059290921b840181019181810190868411156200076e57600080fd5b8286015b84811015620007965780516200078881620006c7565b835291830191830162000772565b509695505050505050565b600082601f830112620007b357600080fd5b81516020620007c66200074883620006fd565b82815260059290921b84018101918181019086841115620007e657600080fd5b8286015b84811015620007965780516200080081620006c7565b8352918301918301620007ea565b80516001600160801b0381168114620006f857600080fd5b6000606082840312156200083957600080fd5b604051606081016001600160401b03811182821017156200085e576200085e62000653565b8060405250809150825180151581146200087757600080fd5b815262000887602084016200080e565b60208201526200089a604084016200080e565b60408201525092915050565b600080600080848603610160811215620008bf57600080fd5b60c0811215620008ce57600080fd5b50620008d962000669565b8551620008e681620006c7565b8152620008f660208701620006e0565b60208201526200090960408701620006e0565b604082015260608601516200091e81620006c7565b606082015260808601516200093381620006c7565b608082015260a08601516200094881620006c7565b60a082015260c08601519094506001600160401b03808211156200096b57600080fd5b620009798883890162000723565b945060e08701519150808211156200099057600080fd5b506200099f87828801620007a1565b925050620009b286610100870162000826565b905092959194509250565b600060208284031215620009d057600080fd5b620005f882620006e0565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a0457600080fd5b815162000a1181620006c7565b9392505050565b60006001820162000a3957634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c05160e0516101005161012051610140516101605161640362000b3260003960008181610381015281816123190152612cdb015260008181610345015281816118090152818161188b015281816122ef0152818161325101526132d801526000612e94015260008181610309015281816122c801526136f30152600081816102a90152818161227601526136d20152600081816102d9015281816122a0015281816128d0015281816136b10152613f1e01526000818161026d015281816122480152612f890152600081816115520152818161159e0152818161194c015261199801526164036000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c80637437ff9f1161012a578063b4069b31116100bd578063d3c7c2c71161008c578063f2fde38b11610071578063f2fde38b146107f4578063f52121a514610807578063f8ccbf471461081a57600080fd5b8063d3c7c2c7146107d9578063d7e2bb50146107e157600080fd5b8063b4069b3114610798578063b5767166146107ab578063c5a1d7f0146107be578063c92b2832146107c657600080fd5b8063856c8247116100f9578063856c82471461071b5780638da5cb5b14610747578063afcb95d714610765578063b1dc65a41461078557600080fd5b80637437ff9f1461060a57806379ba5097146106d557806381ff7048146106dd57806385572ffb1461070d57600080fd5b8063546719cd116101bd578063681fba161161018c5780636c6bd845116101715780636c6bd845146105d1578063704b6c02146105e4578063740f4150146105f757600080fd5b8063681fba161461059c578063693928ae146105b157600080fd5b8063546719cd146104d1578063599f6431146105355780635d86f14114610574578063666cab8d1461058757600080fd5b80632dea00f3116101f95780632dea00f3146104525780633a87ac53146104655780634f9f03fe14610478578063506449721461049957600080fd5b806306285c691461022b578063142a98fc146103d4578063181f5a77146103f45780631ef381741461043d575b600080fd5b6103be6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516103cb919061498a565b60405180910390f35b6103e76103e2366004614a21565b610837565b6040516103cb9190614aa8565b6104306040518060400160405280601481526020017f45564d3245564d4f666652616d7020312e322e3000000000000000000000000081525081565b6040516103cb9190614b24565b61045061044b366004614d92565b6108b2565b005b610450610460366004614e5f565b610d71565b610450610473366004614ee1565b610d7f565b61048b6104863660046151b7565b61118f565b6040516103cb92919061521b565b6104c36104a7366004614a21565b67ffffffffffffffff1660009081526013602052604090205490565b6040519081526020016103cb565b6104d96111a9565b6040516103cb919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103cb565b61054f61058236600461523b565b61125e565b61058f6112c7565b6040516103cb91906152a9565b6105a4611336565b6040516103cb91906152bc565b6105c46105bf36600461539d565b6113ef565b6040516103cb91906154c1565b6104506105df3660046156bd565b611455565b6104506105f236600461523b565b61145f565b6104506106053660046156bd565b61154f565b6106c86040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff808216835273ffffffffffffffffffffffffffffffffffffffff64010000000090920482166020840152600b549182169383019390935261ffff7401000000000000000000000000000000000000000082041660608301527601000000000000000000000000000000000000000000009004909116608082015290565b6040516103cb9190615778565b6104506116d1565b6007546005546040805163ffffffff808516825264010000000090940490931660208401528201526060016103cb565b6104506102263660046157db565b61072e61072936600461523b565b6117ce565b60405167ffffffffffffffff90911681526020016103cb565b60005473ffffffffffffffffffffffffffffffffffffffff1661054f565b6040805160018152600060208201819052918101919091526060016103cb565b610450610793366004615816565b6118f6565b61054f6107a636600461523b565b611b87565b6104506107b93660046158cd565b611c60565b6104c3611c6a565b6104506107d436600461592f565b611c95565b6105a4611d1a565b61054f6107ef36600461523b565b611dcf565b61045061080236600461523b565b611dde565b6104506108153660046151b7565b611def565b6014546108279060ff1681565b60405190151581526020016103cb565b6000610845600160046159cc565b6002610852608085615a0e565b67ffffffffffffffff166108669190615a35565b60136000610875608087615a4c565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156108ac576108ac614a3e565b92915050565b84518460ff16601f821115610928576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6f206d616e79207472616e736d697474657273000000000000000000000060448201526064015b60405180910390fd5b80600003610992576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f7369746976650000000000000000000000000000604482015260640161091f565b61099a612049565b6109a3856120cc565b60095460005b81811015610a2f5760086000600983815481106109c8576109c8615a73565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055610a2881615aa2565b90506109a9565b50875160005b81811015610c2b5760008a8281518110610a5157610a51615a73565b6020026020010151905060006002811115610a6e57610a6e614a3e565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054610100900460ff166002811115610aad57610aad614a3e565b14610b14576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d6974746572206164647265737300000000604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff8116610b61576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c1157610c11614a3e565b02179055509050505080610c2490615aa2565b9050610a35565b508851610c3f9060099060208c01906148f4565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908b161717905560078054610cc5914691309190600090610c979063ffffffff16615ada565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168d8d8d8d8d8d612379565b6005600001819055506000600760049054906101000a900463ffffffff16905043600760046101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600560000154600760009054906101000a900463ffffffff168e8e8e8e8e8e604051610d5c99989796959493929190615afd565b60405180910390a15050505050505050505050565b610d7b8282612424565b5050565b610d87612049565b60005b83811015610f86576000858583818110610da657610da6615a73565b610dbc926020604090920201908101915061523b565b90506000868684818110610dd257610dd2615a73565b9050604002016020016020810190610dea919061523b565b9050610df7600c836124ce565b610e2d576040517f9c8787c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e4f600c846124f0565b73ffffffffffffffffffffffffffffffffffffffff1614610e9c576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea7600c83612512565b50610f228173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ef6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1a9190615b93565b600f90612512565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a1505080610f7f90615aa2565b9050610d8a565b5060005b81811015611188576000838383818110610fa657610fa6615a73565b610fbc926020604090920201908101915061523b565b90506000848484818110610fd257610fd2615a73565b9050604002016020016020810190610fea919061523b565b905073ffffffffffffffffffffffffffffffffffffffff82161580611023575073ffffffffffffffffffffffffffffffffffffffff8116155b1561105a576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611065600c836124ce565b1561109c576040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110a8600c8383612534565b506111248173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111b9190615b93565b600f9083612534565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a150508061118190615aa2565b9050610f8a565b5050505050565b6000606061119d8484612557565b915091505b9250929050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152611259906126fa565b905090565b6000808061126d600c856127ac565b91509150816112c0576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240161091f565b9392505050565b6060600980548060200260200160405190810160405280929190818152602001828054801561132c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611301575b5050505050905090565b6060611342600f6127cf565b67ffffffffffffffff81111561135a5761135a614b37565b604051908082528060200260200182016040528015611383578160200160208202803683370190505b50905060005b81518110156113eb57600061139f600f836127da565b509050808383815181106113b5576113b5615a73565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152506113e481615aa2565b9050611389565b5090565b60606114488989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925061143991508990508a615bb0565b6114438789615bb0565b6127f6565b9998505050505050505050565b610d7b8282612cd9565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061149f575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156114d6576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b467f0000000000000000000000000000000000000000000000000000000000000000146115da576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015267ffffffffffffffff4616602482015260440161091f565b81515181518114611617576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156116c157600083828151811061163657611636615a73565b602002602001015190508060001415801561166f5750845180518390811061166057611660615a73565b60200260200101516080015181105b156116b0576040517f085e39cf000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161091f565b506116ba81615aa2565b905061161a565b506116cc8383612cd9565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611752576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161091f565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff811660009081526012602052604081205467ffffffffffffffff168015801561184157507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b156108ac576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa1580156118d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c09190615bbd565b6119008787613689565b600554883590808214611949576040517f93df584c000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161091f565b467f0000000000000000000000000000000000000000000000000000000000000000146119ca576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015246602482015260440161091f565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff80821684529293919291840191610100909104166002811115611a5257611a52614a3e565b6002811115611a6357611a63614a3e565b9052509050600281602001516002811115611a8057611a80614a3e565b148015611ac757506009816000015160ff1681548110611aa257611aa2615a73565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611afd576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611b0b856020615a35565b611b16886020615a35565b611b228b610144615bda565b611b2c9190615bda565b611b369190615bda565b9050368114611b7a576040517f8e1192e10000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161091f565b5050505050505050505050565b60008080611b96600c856127ac565b9150915081611be9576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240161091f565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c589190615b93565b949350505050565b610d7b8282613689565b60006112597f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b36136ac565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611cd5575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15611d0c576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d17600382613779565b50565b6060611d26600c6127cf565b67ffffffffffffffff811115611d3e57611d3e614b37565b604051908082528060200260200182016040528015611d67578160200160208202803683370190505b50905060005b81518110156113eb576000611d83600c836127da565b50905080838381518110611d9957611d99615a73565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250611dc881615aa2565b9050611d6d565b6000808061126d600f856127ac565b611de6612049565b611d178161395e565b333014611e28576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611e65565b6040805180820190915260008082526020820152815260200190600190039081611e3e5790505b506101408401515190915015611ed257611ecf8361014001518460200151604051602001611eaf919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040528560400151866101600151866127f6565b90505b604083015173ffffffffffffffffffffffffffffffffffffffff163b1580611f3c57506040830151611f3a9073ffffffffffffffffffffffffffffffffffffffff167f85572ffb00000000000000000000000000000000000000000000000000000000613a53565b155b15611f4657505050565b600a546000908190640100000000900473ffffffffffffffffffffffffffffffffffffffff16633cf97983611f7b8786613a6f565b611388886080015189604001516040518563ffffffff1660e01b8152600401611fa79493929190615bed565b6000604051808303816000875af1158015611fc6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261200c9190810190615cbf565b915091508161118857806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161091f9190614b24565b60005473ffffffffffffffffffffffffffffffffffffffff1633146120ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161091f565b565b6000818060200190518101906120e29190615d60565b602081015190915073ffffffffffffffffffffffffffffffffffffffff16612136576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090931663ffffffff9586161792909217909255604080850151600b80546060808901516080808b0151909916760100000000000000000000000000000000000000000000027fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff61ffff90921674010000000000000000000000000000000000000000027fffffffffffffffffffff00000000000000000000000000000000000000000000909416958816959095179290921791909116929092179055815160c0810183527f00000000000000000000000000000000000000000000000000000000000000008416815267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116958201959095527f0000000000000000000000000000000000000000000000000000000000000000909416848301527f00000000000000000000000000000000000000000000000000000000000000008316908401527f00000000000000000000000000000000000000000000000000000000000000008216938301939093527f00000000000000000000000000000000000000000000000000000000000000001660a082015290517f737ef22d3f6615e342ed21c69e06620dbc5c8a261ed7cfb2ce214806b1f76eda9161236d918490615dfb565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a60405160200161239d99989796959493929190615eca565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b60006002612433608085615a0e565b67ffffffffffffffff166124479190615a35565b90506000601381612459608087615a4c565b67ffffffffffffffff168152602081019190915260400160002054905081612483600160046159cc565b901b19168183600381111561249a5761249a614a3e565b901b1780601360006124ad608088615a4c565b67ffffffffffffffff16815260208101919091526040016000205550505050565b60006112c08373ffffffffffffffffffffffffffffffffffffffff8416613b1f565b60006112c08373ffffffffffffffffffffffffffffffffffffffff8416613b2b565b60006112c08373ffffffffffffffffffffffffffffffffffffffff8416613b37565b6000611c588473ffffffffffffffffffffffffffffffffffffffff851684613b43565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a59061259b9087908790600401615fb1565b600060405180830381600087803b1580156125b557600080fd5b505af19250505080156125c6575060015b6126df573d8080156125f4576040519150601f19603f3d011682016040523d82523d6000602084013e6125f9565b606091505b506126038161613b565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0a8d6e8c00000000000000000000000000000000000000000000000000000000148061269b57506126568161613b565b7fffffffff00000000000000000000000000000000000000000000000000000000167fe1cd550900000000000000000000000000000000000000000000000000000000145b156126ab576003925090506111a2565b806040517fcf19edfd00000000000000000000000000000000000000000000000000000000815260040161091f9190614b24565b50506040805160208101909152600081526002909250929050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261278882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261276c91906159cc565b85608001516fffffffffffffffffffffffffffffffff16613b66565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60008061119d8473ffffffffffffffffffffffffffffffffffffffff8516613b85565b60006108ac82613b94565b60008080806127e98686613b9f565b9097909650945050505050565b60606000865167ffffffffffffffff81111561281457612814614b37565b60405190808252806020026020018201604052801561285957816020015b60408051808201909152600080825260208201528152602001906001900390816128325790505b50905060005b8751811015612ca857600061289089838151811061287f5761287f615a73565b60200260200101516000015161125e565b90508073ffffffffffffffffffffffffffffffffffffffff16638627fad689898c86815181106128c2576128c2615a73565b6020026020010151602001517f00000000000000000000000000000000000000000000000000000000000000008b888151811061290157612901615a73565b60200260200101518b898151811061291b5761291b615a73565b602002602001015160405160200161293492919061618b565b6040516020818303038152906040526040518663ffffffff1660e01b81526004016129639594939291906161b0565b600060405180830381600087803b15801561297d57600080fd5b505af192505050801561298e575060015b612bb1573d8080156129bc576040519150601f19603f3d011682016040523d82523d6000602084013e6129c1565b606091505b5060006129cd8261613b565b90507f9725942a000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000082161480612a6057507ff94ebcd1000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b80612aac57507f15279c08000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b80612af857507f1a76572a000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b80612b4457507fd0c8d23a000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008216145b15612b7d57816040517f30dabb5900000000000000000000000000000000000000000000000000000000815260040161091f9190614b24565b816040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161091f9190614b24565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c209190615b93565b838381518110612c3257612c32615a73565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff90911690528851899083908110612c6b57612c6b615a73565b602002602001015160200151838381518110612c8957612c89615a73565b602090810291909101810151015250612ca181615aa2565b905061285f565b50600b54612ccd90829073ffffffffffffffffffffffffffffffffffffffff16613bae565b90505b95945050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d689190616213565b15612d9f576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003612ddc576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114612e1a576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115612e3557612e35614b37565b604051908082528060200260200182016040528015612e5e578160200160208202803683370190505b50905060005b82811015612f3e57600085600001518281518110612e8457612e84615a73565b60200260200101519050612eb8817f0000000000000000000000000000000000000000000000000000000000000000613d96565b838381518110612eca57612eca615a73565b602002602001018181525050806101800151838381518110612eee57612eee615a73565b602002602001015114612f2d576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50612f3781615aa2565b9050612e64565b50604080850151606086015191517f3204887500000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001692633204887592612fbf92879291600401616260565b602060405180830381865afa158015612fdc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130009190616296565b90508060000361303c576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156136805760008760000151828151811061306357613063615a73565b60200260200101519050600061307c8260600151610837565b9050600081600381111561309257613092614a3e565b14806130af575060038160038111156130ad576130ad614a3e565b145b6130f75760608201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b83156131b457600a5460009063ffffffff1661311387426159cc565b11905080806131335750600382600381111561313157613131614a3e565b145b613169576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b88848151811061317b5761317b615a73565b60200260200101516000146131ae5788848151811061319c5761319c615a73565b60200260200101518360800181815250505b50613211565b60008160038111156131c8576131c8614a3e565b146132115760608201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b60208083015173ffffffffffffffffffffffffffffffffffffffff1660009081526012909152604090205467ffffffffffffffff168015801561328957507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b1561342c5760208301516040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015613321573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133459190615bbd565b60c084015190915067ffffffffffffffff166133628260016162af565b67ffffffffffffffff16146133cf57826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a3505050613670565b60208381015173ffffffffffffffffffffffffffffffffffffffff16600090815260129091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600082600381111561344057613440614a3e565b036134cc5760c083015167ffffffffffffffff1661345f8260016162af565b67ffffffffffffffff16146134cc57826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a3505050613670565b60008a6020015185815181106134e4576134e4615a73565b602002602001015190506134f9848251613f1c565b61350884606001516001612424565b6000806135158684612557565b91509150613527866060015183612424565b600382600381111561353b5761353b614a3e565b1415801561355b5750600282600381111561355857613558614a3e565b14155b1561359a578560600151826040517f9e26160300000000000000000000000000000000000000000000000000000000815260040161091f9291906162d0565b60008560038111156135ae576135ae614a3e565b0361361b5760208087015173ffffffffffffffffffffffffffffffffffffffff166000908152601290915260408120805467ffffffffffffffff16916135f3836162ee565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef65848460405161366192919061521b565b60405180910390a35050505050505b61367981615aa2565b9050613043565b50505050505050565b610d7b6136988284018461630b565b604080516000815260208101909152612cd9565b6000817f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000060405160200161375c949392919093845267ffffffffffffffff92831660208501529116604083015273ffffffffffffffffffffffffffffffffffffffff16606082015260800190565b604051602081830303815290604052805190602001209050919050565b81546000906137a290700100000000000000000000000000000000900463ffffffff16426159cc565b9050801561384457600183015483546137ea916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416613b66565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461386a916fffffffffffffffffffffffffffffffff90811691166140f2565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906139519084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036139dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161091f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000613a5e83614108565b80156112c057506112c0838361416c565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff1681526020018460200151604051602001613af4919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b60006112c0838361423b565b60006112c08383614247565b60006112c083836142d1565b6000611c58848473ffffffffffffffffffffffffffffffffffffffff85166142ee565b6000612cd085613b768486615a35565b613b809087615bda565b6140f2565b60008080806127e9868661430b565b60006108ac82614345565b60008080806127e98686614350565b81516000805b82811015613d825760008473ffffffffffffffffffffffffffffffffffffffff1663d02641a0878481518110613bec57613bec615a73565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016040805180830381865afa158015613c60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c849190616340565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613d1657858281518110613cbf57613cbf615a73565b6020908102919091010151516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161091f565b613d64868381518110613d2b57613d2b615a73565b602002602001015160200151827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661437b90919063ffffffff16565b613d6e9084615bda565b92505080613d7b90615aa2565b9050613bb4565b50613d9060038260006143b8565b50505050565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613e3998979695949392919073ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613e7291906154c1565b60405160208183030381529060405280519060200120876101600151604051602001613e9e91906163a0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16826000015167ffffffffffffffff1614613f9c5781516040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b600b54610140830151517401000000000000000000000000000000000000000090910461ffff16101561400d5760608201516040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b80826101400151511461405e5760608201516040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b600b546101208301515176010000000000000000000000000000000000000000000090910463ffffffff161015610d7b57600b54610120830151516040517f8693378900000000000000000000000000000000000000000000000000000000815276010000000000000000000000000000000000000000000090920463ffffffff166004830152602482015260440161091f565b600081831061410157816112c0565b5090919050565b6000614134827f01ffc9a70000000000000000000000000000000000000000000000000000000061416c565b80156108ac5750614165827fffffffff0000000000000000000000000000000000000000000000000000000061416c565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015614224575060208210155b80156142305750600081115b979650505050505050565b60006112c0838361473b565b60008181526002830160205260408120548015158061426b575061426b848461423b565b6112c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640161091f565b600081815260028301602052604081208190556112c08383614753565b60008281526002840160205260408120829055611c58848461475f565b600081815260028301602052604081205481908061433a5761432d858561423b565b9250600091506111a29050565b6001925090506111a2565b60006108ac8261476b565b6000808061435e8585614775565b600081815260029690960160205260409095205494959350505050565b6000670de0b6b3a76400006143ae837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615a35565b6112c091906163b3565b825474010000000000000000000000000000000000000000900460ff1615806143df575081155b156143e957505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061442f90700100000000000000000000000000000000900463ffffffff16426159cc565b905080156144ef5781831115614471576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546144ab9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16613b66565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156145a65773ffffffffffffffffffffffffffffffffffffffff841661454e576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161091f565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161091f565b848310156146b95760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906145ea90826159cc565b6145f4878a6159cc565b6145fe9190615bda565b61460891906163b3565b905073ffffffffffffffffffffffffffffffffffffffff8616614661576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161091f565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161091f565b6146c385846159cc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600081815260018301602052604081205415156112c0565b60006112c08383614781565b60006112c0838361487b565b60006108ac825490565b60006112c083836148ca565b6000818152600183016020526040812054801561486a5760006147a56001836159cc565b85549091506000906147b9906001906159cc565b905081811461481e5760008660000182815481106147d9576147d9615a73565b90600052602060002001549050808760000184815481106147fc576147fc615a73565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061482f5761482f6163c7565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108ac565b60009150506108ac565b5092915050565b60008181526001830160205260408120546148c2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108ac565b5060006108ac565b60008260000182815481106148e1576148e1615a73565b9060005260206000200154905092915050565b82805482825590600052602060002090810192821561496e579160200282015b8281111561496e57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614914565b506113eb9291505b808211156113eb5760008155600101614976565b60c081016108ac828473ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b67ffffffffffffffff81168114611d1757600080fd5b8035614a1c816149fb565b919050565b600060208284031215614a3357600080fd5b81356112c0816149fb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60048110614aa4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016108ac8284614a6d565b60005b83811015614ad1578181015183820152602001614ab9565b50506000910152565b60008151808452614af2816020860160208601614ab6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006112c06020830184614ada565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614b8957614b89614b37565b60405290565b6040516101a0810167ffffffffffffffff81118282101715614b8957614b89614b37565b6040516080810167ffffffffffffffff81118282101715614b8957614b89614b37565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614c1d57614c1d614b37565b604052919050565b600067ffffffffffffffff821115614c3f57614c3f614b37565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611d1757600080fd5b8035614a1c81614c49565b600082601f830112614c8757600080fd5b81356020614c9c614c9783614c25565b614bd6565b82815260059290921b84018101918181019086841115614cbb57600080fd5b8286015b84811015614cdf578035614cd281614c49565b8352918301918301614cbf565b509695505050505050565b803560ff81168114614a1c57600080fd5b600067ffffffffffffffff821115614d1557614d15614b37565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112614d5257600080fd5b8135614d60614c9782614cfb565b818152846020838601011115614d7557600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614dab57600080fd5b863567ffffffffffffffff80821115614dc357600080fd5b614dcf8a838b01614c76565b97506020890135915080821115614de557600080fd5b614df18a838b01614c76565b9650614dff60408a01614cea565b95506060890135915080821115614e1557600080fd5b614e218a838b01614d41565b9450614e2f60808a01614a11565b935060a0890135915080821115614e4557600080fd5b50614e5289828a01614d41565b9150509295509295509295565b60008060408385031215614e7257600080fd5b8235614e7d816149fb565b9150602083013560048110614e9157600080fd5b809150509250929050565b60008083601f840112614eae57600080fd5b50813567ffffffffffffffff811115614ec657600080fd5b6020830191508360208260061b85010111156111a257600080fd5b60008060008060408587031215614ef757600080fd5b843567ffffffffffffffff80821115614f0f57600080fd5b614f1b88838901614e9c565b90965094506020870135915080821115614f3457600080fd5b50614f4187828801614e9c565b95989497509550505050565b8015158114611d1757600080fd5b8035614a1c81614f4d565b600082601f830112614f7757600080fd5b81356020614f87614c9783614c25565b82815260069290921b84018101918181019086841115614fa657600080fd5b8286015b84811015614cdf5760408189031215614fc35760008081fd5b614fcb614b66565b8135614fd681614c49565b81528185013585820152835291830191604001614faa565b6000614ffc614c9784614c25565b8381529050602080820190600585901b84018681111561501b57600080fd5b845b8181101561505757803567ffffffffffffffff81111561503d5760008081fd5b61504989828901614d41565b85525092820192820161501d565b505050509392505050565b600082601f83011261507357600080fd5b6112c083833560208501614fee565b60006101a0828403121561509557600080fd5b61509d614b8f565b90506150a882614a11565b81526150b660208301614c6b565b60208201526150c760408301614c6b565b60408201526150d860608301614a11565b6060820152608082013560808201526150f360a08301614f5b565b60a082015261510460c08301614a11565b60c082015261511560e08301614c6b565b60e082015261010082810135908201526101208083013567ffffffffffffffff8082111561514257600080fd5b61514e86838701614d41565b8385015261014092508285013591508082111561516a57600080fd5b61517686838701614f66565b8385015261016092508285013591508082111561519257600080fd5b5061519f85828601615062565b82840152505061018080830135818301525092915050565b600080604083850312156151ca57600080fd5b823567ffffffffffffffff808211156151e257600080fd5b6151ee86838701615082565b9350602085013591508082111561520457600080fd5b5061521185828601615062565b9150509250929050565b6152258184614a6d565b604060208201526000611c586040830184614ada565b60006020828403121561524d57600080fd5b81356112c081614c49565b600081518084526020808501945080840160005b8381101561529e57815173ffffffffffffffffffffffffffffffffffffffff168752958201959082019060010161526c565b509495945050505050565b6020815260006112c06020830184615258565b6020808252825182820181905260009190848201906040850190845b8181101561530a57835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016152d8565b50909695505050505050565b60008083601f84011261532857600080fd5b50813567ffffffffffffffff81111561534057600080fd5b6020830191508360208285010111156111a257600080fd5b60008083601f84011261536a57600080fd5b50813567ffffffffffffffff81111561538257600080fd5b6020830191508360208260051b85010111156111a257600080fd5b60008060008060008060008060a0898b0312156153b957600080fd5b883567ffffffffffffffff808211156153d157600080fd5b6153dd8c838d01614f66565b995060208b01359150808211156153f357600080fd5b6153ff8c838d01615316565b909950975060408b0135915061541482614c49565b90955060608a0135908082111561542a57600080fd5b6154368c838d01615358565b909650945060808b013591508082111561544f57600080fd5b5061545c8b828c01615358565b999c989b5096995094979396929594505050565b600081518084526020808501945080840160005b8381101561529e578151805173ffffffffffffffffffffffffffffffffffffffff1688528301518388015260409096019590820190600101615484565b6020815260006112c06020830184615470565b600082601f8301126154e557600080fd5b813560206154f5614c9783614c25565b82815260059290921b8401810191818101908684111561551457600080fd5b8286015b84811015614cdf57803567ffffffffffffffff8111156155385760008081fd5b6155468986838b0101615062565b845250918301918301615518565b600082601f83011261556557600080fd5b81356020615575614c9783614c25565b82815260059290921b8401810191818101908684111561559457600080fd5b8286015b84811015614cdf5780358352918301918301615598565b6000608082840312156155c157600080fd5b6155c9614bb3565b9050813567ffffffffffffffff808211156155e357600080fd5b818401915084601f8301126155f757600080fd5b81356020615607614c9783614c25565b82815260059290921b8401810191818101908884111561562657600080fd5b8286015b8481101561565e578035868111156156425760008081fd5b6156508b86838b0101615082565b84525091830191830161562a565b508652508581013593508284111561567557600080fd5b615681878588016154d4565b9085015250604084013591508082111561569a57600080fd5b506156a784828501615554565b6040830152506060820135606082015292915050565b600080604083850312156156d057600080fd5b823567ffffffffffffffff808211156156e857600080fd5b6156f4868387016155af565b935060209150818501358181111561570b57600080fd5b85019050601f8101861361571e57600080fd5b803561572c614c9782614c25565b81815260059190911b8201830190838101908883111561574b57600080fd5b928401925b8284101561576957833582529284019290840190615750565b80955050505050509250929050565b60a081016108ac828463ffffffff808251168352602082015173ffffffffffffffffffffffffffffffffffffffff8082166020860152806040850151166040860152505061ffff6060830151166060840152806080830151166080840152505050565b6000602082840312156157ed57600080fd5b813567ffffffffffffffff81111561580457600080fd5b820160a081850312156112c057600080fd5b60008060008060008060008060e0898b03121561583257600080fd5b606089018a81111561584357600080fd5b8998503567ffffffffffffffff8082111561585d57600080fd5b6158698c838d01615316565b909950975060808b013591508082111561588257600080fd5b61588e8c838d01615358565b909750955060a08b01359150808211156158a757600080fd5b506158b48b828c01615358565b999c989b50969995989497949560c00135949350505050565b600080602083850312156158e057600080fd5b823567ffffffffffffffff8111156158f757600080fd5b61590385828601615316565b90969095509350505050565b80356fffffffffffffffffffffffffffffffff81168114614a1c57600080fd5b60006060828403121561594157600080fd5b6040516060810181811067ffffffffffffffff8211171561596457615964614b37565b604052823561597281614f4d565b81526159806020840161590f565b60208201526159916040840161590f565b60408201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156108ac576108ac61599d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680615a2957615a296159df565b92169190910692915050565b80820281158282048414176108ac576108ac61599d565b600067ffffffffffffffff80841680615a6757615a676159df565b92169190910492915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615ad357615ad361599d565b5060010190565b600063ffffffff808316818103615af357615af361599d565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b16604085015250806060840152615b2d8184018a615258565b90508281036080840152615b418189615258565b905060ff871660a084015282810360c0840152615b5e8187614ada565b905067ffffffffffffffff851660e0840152828103610100840152615b838185614ada565b9c9b505050505050505050505050565b600060208284031215615ba557600080fd5b81516112c081614c49565b60006112c0368484614fee565b600060208284031215615bcf57600080fd5b81516112c0816149fb565b808201808211156108ac576108ac61599d565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152615c28610120840182614ada565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152615c648383614ada565b925060808901519150808584030161010086015250615c838282615470565b92505050615c97602083018661ffff169052565b836040830152612cd0606083018473ffffffffffffffffffffffffffffffffffffffff169052565b60008060408385031215615cd257600080fd5b8251615cdd81614f4d565b602084015190925067ffffffffffffffff811115615cfa57600080fd5b8301601f81018513615d0b57600080fd5b8051615d19614c9782614cfb565b818152866020838501011115615d2e57600080fd5b615d3f826020830160208601614ab6565b8093505050509250929050565b805163ffffffff81168114614a1c57600080fd5b600060a08284031215615d7257600080fd5b60405160a0810181811067ffffffffffffffff82111715615d9557615d95614b37565b604052615da183615d4c565b81526020830151615db181614c49565b60208201526040830151615dc481614c49565b6040820152606083015161ffff81168114615dde57600080fd5b6060820152615def60808401615d4c565b60808201529392505050565b6101608101615e6d828573ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b825163ffffffff90811660c0840152602084015173ffffffffffffffffffffffffffffffffffffffff90811660e0850152604085015116610100840152606084015161ffff166101208401526080840151166101408301526112c0565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152615f118285018b615258565b91508382036080850152615f25828a615258565b915060ff881660a085015283820360c0850152615f428288614ada565b90861660e08501528381036101008501529050615b838185614ada565b6000815180845260208085019450848260051b860182860160005b85811015615fa4578383038952615f92838351614ada565b98850198925090840190600101615f7a565b5090979650505050505050565b60408152615fcc60408201845167ffffffffffffffff169052565b60006020840151615ff5606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604084015173ffffffffffffffffffffffffffffffffffffffff8116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c08401516101006160638185018367ffffffffffffffff169052565b60e0860151915061012061608e8186018473ffffffffffffffffffffffffffffffffffffffff169052565b81870151925061014091508282860152808701519250506101a061016081818701526160be6101e0870185614ada565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc06101808188870301818901526160fd8686615470565b9550828a015194508188870301848901526161188686615f5f565b9550808a01516101c089015250505050508281036020840152612cd08185615f5f565b6000815160208301517fffffffff00000000000000000000000000000000000000000000000000000000808216935060048310156161835780818460040360031b1b83161693505b505050919050565b60408152600061619e6040830185614ada565b8281036020840152612cd08185614ada565b60a0815260006161c360a0830188614ada565b73ffffffffffffffffffffffffffffffffffffffff8716602084015285604084015267ffffffffffffffff8516606084015282810360808401526162078185614ada565b98975050505050505050565b60006020828403121561622557600080fd5b81516112c081614f4d565b600081518084526020808501945080840160005b8381101561529e57815187529582019590820190600101616244565b6060815260006162736060830186616230565b82810360208401526162858186616230565b915050826040830152949350505050565b6000602082840312156162a857600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156148745761487461599d565b67ffffffffffffffff83168152604081016112c06020830184614a6d565b600067ffffffffffffffff808316818103615af357615af361599d565b60006020828403121561631d57600080fd5b813567ffffffffffffffff81111561633457600080fd5b611c58848285016155af565b60006040828403121561635257600080fd5b61635a614b66565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116811461638657600080fd5b815261639460208401615d4c565b60208201529392505050565b6020815260006112c06020830184615f5f565b6000826163c2576163c26159df565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", + Bin: "0x6101806040526014805460ff191660011790553480156200001f57600080fd5b5060405162006d7a38038062006d7a8339810160408190526200004291620008a6565b838383838033806000816200009e5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d157620000d1816200048d565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080938401819052600380546001600160a01b031916909517600160801b9384021760ff60a01b1916600160a01b90920291909117909355909102909217600455504690528151835114620001815760405162d8548360e71b815260040160405180910390fd5b60608401516001600160a01b03161580620001a4575083516001600160a01b0316155b15620001c3576040516342bcdf7f60e11b815260040160405180910390fd5b83600001516001600160a01b0316634120fccd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000206573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022c9190620009bd565b6001600160401b03166001146200025657604051636fc2a20760e11b815260040160405180910390fd5b83516001600160a01b0390811660a090815260408601516001600160401b0390811660c05260208701511660e052606086015182166101005260808601518216610140528501511661016052620002cd7f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b362000538565b6101205260005b83518110156200047e576200032e848281518110620002f757620002f7620009db565b6020026020010151848381518110620003145762000314620009db565b6020026020010151600c6200059f60201b9092919060201c565b50620003e3838281518110620003485762000348620009db565b60200260200101516001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200038e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003b49190620009f1565b848381518110620003c957620003c9620009db565b6020026020010151600f6200059f60201b9092919060201c565b507f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c8482815181106200041a576200041a620009db565b6020026020010151848381518110620004375762000437620009db565b6020026020010151604051620004639291906001600160a01b0392831681529116602082015260400190565b60405180910390a1620004768162000a18565b9050620002d4565b50505050505050505062000a40565b336001600160a01b03821603620004e75760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000095565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60008160c05160e051610100516040516020016200058294939291909384526001600160401b039283166020850152911660408301526001600160a01b0316606082015260800190565b604051602081830303815290604052805190602001209050919050565b6000620005b7846001600160a01b03851684620005bf565b949350505050565b6000620005b784846001600160a01b03851660008281526002840160205260408120829055620005b784846000620005f8838362000601565b90505b92915050565b60008181526001830160205260408120546200064a57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005fb565b506000620005fb565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b03811182821017156200068e576200068e62000653565b60405290565b604051601f8201601f191681016001600160401b0381118282101715620006bf57620006bf62000653565b604052919050565b6001600160a01b0381168114620006dd57600080fd5b50565b80516001600160401b0381168114620006f857600080fd5b919050565b60006001600160401b0382111562000719576200071962000653565b5060051b60200190565b600082601f8301126200073557600080fd5b815160206200074e6200074883620006fd565b62000694565b82815260059290921b840181019181810190868411156200076e57600080fd5b8286015b84811015620007965780516200078881620006c7565b835291830191830162000772565b509695505050505050565b600082601f830112620007b357600080fd5b81516020620007c66200074883620006fd565b82815260059290921b84018101918181019086841115620007e657600080fd5b8286015b84811015620007965780516200080081620006c7565b8352918301918301620007ea565b80516001600160801b0381168114620006f857600080fd5b6000606082840312156200083957600080fd5b604051606081016001600160401b03811182821017156200085e576200085e62000653565b8060405250809150825180151581146200087757600080fd5b815262000887602084016200080e565b60208201526200089a604084016200080e565b60408201525092915050565b600080600080848603610160811215620008bf57600080fd5b60c0811215620008ce57600080fd5b50620008d962000669565b8551620008e681620006c7565b8152620008f660208701620006e0565b60208201526200090960408701620006e0565b604082015260608601516200091e81620006c7565b606082015260808601516200093381620006c7565b608082015260a08601516200094881620006c7565b60a082015260c08601519094506001600160401b03808211156200096b57600080fd5b620009798883890162000723565b945060e08701519150808211156200099057600080fd5b506200099f87828801620007a1565b925050620009b286610100870162000826565b905092959194509250565b600060208284031215620009d057600080fd5b620005f882620006e0565b634e487b7160e01b600052603260045260246000fd5b60006020828403121562000a0457600080fd5b815162000a1181620006c7565b9392505050565b60006001820162000a3957634e487b7160e01b600052601160045260246000fd5b5060010190565b60805160a05160c05160e0516101005161012051610140516101605161624862000b3260003960008181610381015281816123190152612b20015260008181610345015281816118090152818161188b015281816122ef01528181613096015261311d01526000612cd9015260008181610309015281816122c801526135380152600081816102a90152818161227601526135170152600081816102d9015281816122a0015281816128d0015281816134f60152613d6301526000818161026d015281816122480152612dce0152600081816115520152818161159e0152818161194c015261199801526162486000f3fe608060405234801561001057600080fd5b50600436106102265760003560e01c80637437ff9f1161012a578063b4069b31116100bd578063d3c7c2c71161008c578063f2fde38b11610071578063f2fde38b146107f4578063f52121a514610807578063f8ccbf471461081a57600080fd5b8063d3c7c2c7146107d9578063d7e2bb50146107e157600080fd5b8063b4069b3114610798578063b5767166146107ab578063c5a1d7f0146107be578063c92b2832146107c657600080fd5b8063856c8247116100f9578063856c82471461071b5780638da5cb5b14610747578063afcb95d714610765578063b1dc65a41461078557600080fd5b80637437ff9f1461060a57806379ba5097146106d557806381ff7048146106dd57806385572ffb1461070d57600080fd5b8063546719cd116101bd578063681fba161161018c5780636c6bd845116101715780636c6bd845146105d1578063704b6c02146105e4578063740f4150146105f757600080fd5b8063681fba161461059c578063693928ae146105b157600080fd5b8063546719cd146104d1578063599f6431146105355780635d86f14114610574578063666cab8d1461058757600080fd5b80632dea00f3116101f95780632dea00f3146104525780633a87ac53146104655780634f9f03fe14610478578063506449721461049957600080fd5b806306285c691461022b578063142a98fc146103d4578063181f5a77146103f45780631ef381741461043d575b600080fd5b6103be6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526040518060c001604052807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16815250905090565b6040516103cb91906147cf565b60405180910390f35b6103e76103e2366004614866565b610837565b6040516103cb91906148ed565b6104306040518060400160405280601481526020017f45564d3245564d4f666652616d7020312e322e3000000000000000000000000081525081565b6040516103cb9190614969565b61045061044b366004614bd7565b6108b2565b005b610450610460366004614ca4565b610d71565b610450610473366004614d26565b610d7f565b61048b610486366004614ffc565b61118f565b6040516103cb929190615060565b6104c36104a7366004614866565b67ffffffffffffffff1660009081526013602052604090205490565b6040519081526020016103cb565b6104d96111a9565b6040516103cb919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b60025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103cb565b61054f610582366004615080565b61125e565b61058f6112c7565b6040516103cb91906150ee565b6105a4611336565b6040516103cb9190615101565b6105c46105bf3660046151e2565b6113ef565b6040516103cb9190615306565b6104506105df366004615502565b611455565b6104506105f2366004615080565b61145f565b610450610605366004615502565b61154f565b6106c86040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506040805160a081018252600a5463ffffffff808216835273ffffffffffffffffffffffffffffffffffffffff64010000000090920482166020840152600b549182169383019390935261ffff7401000000000000000000000000000000000000000082041660608301527601000000000000000000000000000000000000000000009004909116608082015290565b6040516103cb91906155bd565b6104506116d1565b6007546005546040805163ffffffff808516825264010000000090940490931660208401528201526060016103cb565b610450610226366004615620565b61072e610729366004615080565b6117ce565b60405167ffffffffffffffff90911681526020016103cb565b60005473ffffffffffffffffffffffffffffffffffffffff1661054f565b6040805160018152600060208201819052918101919091526060016103cb565b61045061079336600461565b565b6118f6565b61054f6107a6366004615080565b611b87565b6104506107b9366004615712565b611c60565b6104c3611c6a565b6104506107d4366004615774565b611c95565b6105a4611d1a565b61054f6107ef366004615080565b611dcf565b610450610802366004615080565b611dde565b610450610815366004614ffc565b611def565b6014546108279060ff1681565b60405190151581526020016103cb565b600061084560016004615811565b6002610852608085615853565b67ffffffffffffffff16610866919061587a565b60136000610875608087615891565b67ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002054901c1660038111156108ac576108ac614883565b92915050565b84518460ff16601f821115610928576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f746f6f206d616e79207472616e736d697474657273000000000000000000000060448201526064015b60405180910390fd5b80600003610992576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f66206d75737420626520706f7369746976650000000000000000000000000000604482015260640161091f565b61099a612049565b6109a3856120cc565b60095460005b81811015610a2f5760086000600983815481106109c8576109c86158b8565b600091825260208083209091015473ffffffffffffffffffffffffffffffffffffffff168352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000169055610a28816158e7565b90506109a9565b50875160005b81811015610c2b5760008a8281518110610a5157610a516158b8565b6020026020010151905060006002811115610a6e57610a6e614883565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902054610100900460ff166002811115610aad57610aad614883565b14610b14576040517f89a6198900000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f7265706561746564207472616e736d6974746572206164647265737300000000604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff8116610b61576040517fd6c62c9b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805180820190915260ff83168152602081016002905273ffffffffffffffffffffffffffffffffffffffff821660009081526008602090815260409091208251815460ff9091167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0082168117835592840151919283917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001617610100836002811115610c1157610c11614883565b02179055509050505080610c24906158e7565b9050610a35565b508851610c3f9060099060208c0190614739565b506006805460ff838116610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000909216908b161717905560078054610cc5914691309190600090610c979063ffffffff1661591f565b91906101000a81548163ffffffff021916908363ffffffff160217905563ffffffff168d8d8d8d8d8d612379565b6005600001819055506000600760049054906101000a900463ffffffff16905043600760046101000a81548163ffffffff021916908363ffffffff1602179055507f1591690b8638f5fb2dbec82ac741805ac5da8b45dc5263f4875b0496fdce4e0581600560000154600760009054906101000a900463ffffffff168e8e8e8e8e8e604051610d5c99989796959493929190615942565b60405180910390a15050505050505050505050565b610d7b8282612424565b5050565b610d87612049565b60005b83811015610f86576000858583818110610da657610da66158b8565b610dbc9260206040909202019081019150615080565b90506000868684818110610dd257610dd26158b8565b9050604002016020016020810190610dea9190615080565b9050610df7600c836124ce565b610e2d576040517f9c8787c000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610e4f600c846124f0565b73ffffffffffffffffffffffffffffffffffffffff1614610e9c576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ea7600c83612512565b50610f228173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ef6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1a91906159d8565b600f90612512565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a1505080610f7f906158e7565b9050610d8a565b5060005b81811015611188576000838383818110610fa657610fa66158b8565b610fbc9260206040909202019081019150615080565b90506000848484818110610fd257610fd26158b8565b9050604002016020016020810190610fea9190615080565b905073ffffffffffffffffffffffffffffffffffffffff82161580611023575073ffffffffffffffffffffffffffffffffffffffff8116155b1561105a576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611065600c836124ce565b1561109c576040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110a8600c8383612534565b506111248173ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111b91906159d8565b600f9083612534565b506040805173ffffffffffffffffffffffffffffffffffffffff8085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a1505080611181906158e7565b9050610f8a565b5050505050565b6000606061119d8484612557565b915091505b9250929050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152611259906126fa565b905090565b6000808061126d600c856127ac565b91509150816112c0576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240161091f565b9392505050565b6060600980548060200260200160405190810160405280929190818152602001828054801561132c57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311611301575b5050505050905090565b6060611342600f6127cf565b67ffffffffffffffff81111561135a5761135a61497c565b604051908082528060200260200182016040528015611383578160200160208202803683370190505b50905060005b81518110156113eb57600061139f600f836127da565b509050808383815181106113b5576113b56158b8565b73ffffffffffffffffffffffffffffffffffffffff90921660209283029190910190910152506113e4816158e7565b9050611389565b5090565b60606114488989898080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508b925061143991508990508a6159f5565b61144387896159f5565b6127f6565b9998505050505050505050565b610d7b8282612b1e565b60005473ffffffffffffffffffffffffffffffffffffffff16331480159061149f575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156114d6576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c9060200160405180910390a150565b467f0000000000000000000000000000000000000000000000000000000000000000146115da576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015267ffffffffffffffff4616602482015260440161091f565b81515181518114611617576040517f83e3f56400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b818110156116c1576000838281518110611636576116366158b8565b602002602001015190508060001415801561166f57508451805183908110611660576116606158b8565b60200260200101516080015181105b156116b0576040517f085e39cf000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260440161091f565b506116ba816158e7565b905061161a565b506116cc8383612b1e565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611752576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161091f565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b73ffffffffffffffffffffffffffffffffffffffff811660009081526012602052604081205467ffffffffffffffff168015801561184157507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b156108ac576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa1580156118d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c09190615a02565b61190087876134ce565b600554883590808214611949576040517f93df584c000000000000000000000000000000000000000000000000000000008152600481018290526024810183905260440161091f565b467f0000000000000000000000000000000000000000000000000000000000000000146119ca576040517f0f01ce850000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015246602482015260440161091f565b6040805183815260208c81013560081c63ffffffff16908201527fb04e63db38c49950639fa09d29872f21f5d49d614f3a969d8adf3d4b52e41a62910160405180910390a13360009081526008602090815260408083208151808301909252805460ff80821684529293919291840191610100909104166002811115611a5257611a52614883565b6002811115611a6357611a63614883565b9052509050600281602001516002811115611a8057611a80614883565b148015611ac757506009816000015160ff1681548110611aa257611aa26158b8565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff1633145b611afd576040517fda0f08e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000611b0b85602061587a565b611b1688602061587a565b611b228b610144615a1f565b611b2c9190615a1f565b611b369190615a1f565b9050368114611b7a576040517f8e1192e10000000000000000000000000000000000000000000000000000000081526004810182905236602482015260440161091f565b5050505050505050505050565b60008080611b96600c856127ac565b9150915081611be9576040517fbf16aab600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015260240161091f565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c5891906159d8565b949350505050565b610d7b82826134ce565b60006112597f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b36134f1565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611cd5575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15611d0c576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d176003826135be565b50565b6060611d26600c6127cf565b67ffffffffffffffff811115611d3e57611d3e61497c565b604051908082528060200260200182016040528015611d67578160200160208202803683370190505b50905060005b81518110156113eb576000611d83600c836127da565b50905080838381518110611d9957611d996158b8565b73ffffffffffffffffffffffffffffffffffffffff9092166020928302919091019091015250611dc8816158e7565b9050611d6d565b6000808061126d600f856127ac565b611de6612049565b611d17816137a3565b333014611e28576040517f371a732800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160008082526020820190925281611e65565b6040805180820190915260008082526020820152815260200190600190039081611e3e5790505b506101408401515190915015611ed257611ecf8361014001518460200151604051602001611eaf919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040528560400151866101600151866127f6565b90505b604083015173ffffffffffffffffffffffffffffffffffffffff163b1580611f3c57506040830151611f3a9073ffffffffffffffffffffffffffffffffffffffff167f85572ffb00000000000000000000000000000000000000000000000000000000613898565b155b15611f4657505050565b600a546000908190640100000000900473ffffffffffffffffffffffffffffffffffffffff16633cf97983611f7b87866138b4565b611388886080015189604001516040518563ffffffff1660e01b8152600401611fa79493929190615a32565b6000604051808303816000875af1158015611fc6573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261200c9190810190615b04565b915091508161118857806040517f0a8d6e8c00000000000000000000000000000000000000000000000000000000815260040161091f9190614969565b60005473ffffffffffffffffffffffffffffffffffffffff1633146120ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161091f565b565b6000818060200190518101906120e29190615ba5565b602081015190915073ffffffffffffffffffffffffffffffffffffffff16612136576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8051600a805460208085015173ffffffffffffffffffffffffffffffffffffffff908116640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090931663ffffffff9586161792909217909255604080850151600b80546060808901516080808b0151909916760100000000000000000000000000000000000000000000027fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff61ffff90921674010000000000000000000000000000000000000000027fffffffffffffffffffff00000000000000000000000000000000000000000000909416958816959095179290921791909116929092179055815160c0810183527f00000000000000000000000000000000000000000000000000000000000000008416815267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116958201959095527f0000000000000000000000000000000000000000000000000000000000000000909416848301527f00000000000000000000000000000000000000000000000000000000000000008316908401527f00000000000000000000000000000000000000000000000000000000000000008216938301939093527f00000000000000000000000000000000000000000000000000000000000000001660a082015290517f737ef22d3f6615e342ed21c69e06620dbc5c8a261ed7cfb2ce214806b1f76eda9161236d918490615c40565b60405180910390a15050565b6000808a8a8a8a8a8a8a8a8a60405160200161239d99989796959493929190615d0f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101207dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167e01000000000000000000000000000000000000000000000000000000000000179150509998505050505050505050565b60006002612433608085615853565b67ffffffffffffffff16612447919061587a565b90506000601381612459608087615891565b67ffffffffffffffff16815260208101919091526040016000205490508161248360016004615811565b901b19168183600381111561249a5761249a614883565b901b1780601360006124ad608088615891565b67ffffffffffffffff16815260208101919091526040016000205550505050565b60006112c08373ffffffffffffffffffffffffffffffffffffffff8416613964565b60006112c08373ffffffffffffffffffffffffffffffffffffffff8416613970565b60006112c08373ffffffffffffffffffffffffffffffffffffffff841661397c565b6000611c588473ffffffffffffffffffffffffffffffffffffffff851684613988565b6040517ff52121a5000000000000000000000000000000000000000000000000000000008152600090606090309063f52121a59061259b9087908790600401615df6565b600060405180830381600087803b1580156125b557600080fd5b505af19250505080156125c6575060015b6126df573d8080156125f4576040519150601f19603f3d011682016040523d82523d6000602084013e6125f9565b606091505b5061260381615f80565b7fffffffff00000000000000000000000000000000000000000000000000000000167f0a8d6e8c00000000000000000000000000000000000000000000000000000000148061269b575061265681615f80565b7fffffffff00000000000000000000000000000000000000000000000000000000167fe1cd550900000000000000000000000000000000000000000000000000000000145b156126ab576003925090506111a2565b806040517fcf19edfd00000000000000000000000000000000000000000000000000000000815260040161091f9190614969565b50506040805160208101909152600081526002909250929050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261278882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff164261276c9190615811565b85608001516fffffffffffffffffffffffffffffffff166139ab565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b60008061119d8473ffffffffffffffffffffffffffffffffffffffff85166139ca565b60006108ac826139d9565b60008080806127e986866139e4565b9097909650945050505050565b60606000865167ffffffffffffffff8111156128145761281461497c565b60405190808252806020026020018201604052801561285957816020015b60408051808201909152600080825260208201528152602001906001900390816128325790505b50905060005b8751811015612aed57600061289089838151811061287f5761287f6158b8565b60200260200101516000015161125e565b90508073ffffffffffffffffffffffffffffffffffffffff16638627fad689898c86815181106128c2576128c26158b8565b6020026020010151602001517f00000000000000000000000000000000000000000000000000000000000000008b8881518110612901576129016158b8565b60200260200101518b898151811061291b5761291b6158b8565b6020026020010151604051602001612934929190615fd0565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401612963959493929190615ff5565b600060405180830381600087803b15801561297d57600080fd5b505af192505050801561298e575060015b6129f6573d8080156129bc576040519150601f19603f3d011682016040523d82523d6000602084013e6129c1565b606091505b50806040517fe1cd550900000000000000000000000000000000000000000000000000000000815260040161091f9190614969565b8073ffffffffffffffffffffffffffffffffffffffff166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a6591906159d8565b838381518110612a7757612a776158b8565b602090810291909101015173ffffffffffffffffffffffffffffffffffffffff90911690528851899083908110612ab057612ab06158b8565b602002602001015160200151838381518110612ace57612ace6158b8565b602090810291909101810151015250612ae6816158e7565b905061285f565b50600b54612b1290829073ffffffffffffffffffffffffffffffffffffffff166139f3565b90505b95945050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bad9190616058565b15612be4576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8151516000819003612c21576040517ebf199700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260200151518114612c5f576040517f57e0e08300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008167ffffffffffffffff811115612c7a57612c7a61497c565b604051908082528060200260200182016040528015612ca3578160200160208202803683370190505b50905060005b82811015612d8357600085600001518281518110612cc957612cc96158b8565b60200260200101519050612cfd817f0000000000000000000000000000000000000000000000000000000000000000613bdb565b838381518110612d0f57612d0f6158b8565b602002602001018181525050806101800151838381518110612d3357612d336158b8565b602002602001015114612d72576040517f7185cf6b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50612d7c816158e7565b9050612ca9565b50604080850151606086015191517f3204887500000000000000000000000000000000000000000000000000000000815260009273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001692633204887592612e04928792916004016160a5565b602060405180830381865afa158015612e21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e4591906160db565b905080600003612e81576040517fea75680100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8351151560005b848110156134c557600087600001518281518110612ea857612ea86158b8565b602002602001015190506000612ec18260600151610837565b90506000816003811115612ed757612ed7614883565b1480612ef457506003816003811115612ef257612ef2614883565b145b612f3c5760608201516040517f50a6e05200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b8315612ff957600a5460009063ffffffff16612f588742615811565b1190508080612f7857506003826003811115612f7657612f76614883565b145b612fae576040517f6358b0d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b888481518110612fc057612fc06158b8565b6020026020010151600014612ff357888481518110612fe157612fe16158b8565b60200260200101518360800181815250505b50613056565b600081600381111561300d5761300d614883565b146130565760608201516040517f67d9ba0f00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b60208083015173ffffffffffffffffffffffffffffffffffffffff1660009081526012909152604090205467ffffffffffffffff16801580156130ce57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1615155b156132715760208301516040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527f00000000000000000000000000000000000000000000000000000000000000009091169063856c824790602401602060405180830381865afa158015613166573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061318a9190615a02565b60c084015190915067ffffffffffffffff166131a78260016160f4565b67ffffffffffffffff161461321457826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fe44a20935573a783dd0d5991c92d7b6a0eb3173566530364db3ec10e9a990b5d60405160405180910390a35050506134b5565b60208381015173ffffffffffffffffffffffffffffffffffffffff16600090815260129091526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83161790555b600082600381111561328557613285614883565b036133115760c083015167ffffffffffffffff166132a48260016160f4565b67ffffffffffffffff161461331157826020015173ffffffffffffffffffffffffffffffffffffffff168360c0015167ffffffffffffffff167fd32ddb11d71e3d63411d37b09f9a8b28664f1cb1338bfd1413c173b0ebf4123760405160405180910390a35050506134b5565b60008a602001518581518110613329576133296158b8565b6020026020010151905061333e848251613d61565b61334d84606001516001612424565b60008061335a8684612557565b9150915061336c866060015183612424565b600382600381111561338057613380614883565b141580156133a05750600282600381111561339d5761339d614883565b14155b156133df578560600151826040517f9e26160300000000000000000000000000000000000000000000000000000000815260040161091f929190616115565b60008560038111156133f3576133f3614883565b036134605760208087015173ffffffffffffffffffffffffffffffffffffffff166000908152601290915260408120805467ffffffffffffffff169161343883616133565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505b856101800151866060015167ffffffffffffffff167fd4f851956a5d67c3997d1c9205045fef79bae2947fdee7e9e2641abc7391ef6584846040516134a6929190615060565b60405180910390a35050505050505b6134be816158e7565b9050612e88565b50505050505050565b610d7b6134dd82840184616150565b604080516000815260208101909152612b1e565b6000817f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006040516020016135a1949392919093845267ffffffffffffffff92831660208501529116604083015273ffffffffffffffffffffffffffffffffffffffff16606082015260800190565b604051602081830303815290604052805190602001209050919050565b81546000906135e790700100000000000000000000000000000000900463ffffffff1642615811565b90508015613689576001830154835461362f916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166139ab565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546136af916fffffffffffffffffffffffffffffffff9081169116613f37565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906137969084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60405180910390a1505050565b3373ffffffffffffffffffffffffffffffffffffffff821603613822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161091f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006138a383613f4d565b80156112c057506112c08383613fb1565b6040805160a08101825260008082526020820152606091810182905281810182905260808101919091526040518060a001604052808461018001518152602001846000015167ffffffffffffffff1681526020018460200151604051602001613939919073ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b6040516020818303038152906040528152602001846101200151815260200183815250905092915050565b60006112c08383614080565b60006112c0838361408c565b60006112c08383614116565b6000611c58848473ffffffffffffffffffffffffffffffffffffffff8516614133565b6000612b15856139bb848661587a565b6139c59087615a1f565b613f37565b60008080806127e98686614150565b60006108ac8261418a565b60008080806127e98686614195565b81516000805b82811015613bc75760008473ffffffffffffffffffffffffffffffffffffffff1663d02641a0878481518110613a3157613a316158b8565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016040805180830381865afa158015613aa5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ac99190616185565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613b5b57858281518110613b0457613b046158b8565b6020908102919091010151516040517f9a655f7b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015260240161091f565b613ba9868381518110613b7057613b706158b8565b602002602001015160200151827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166141c090919063ffffffff16565b613bb39084615a1f565b92505080613bc0906158e7565b90506139f9565b50613bd560038260006141fd565b50505050565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b6101000151604051602001613c7e98979695949392919073ffffffffffffffffffffffffffffffffffffffff9889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b6040516020818303038152906040528051906020012085610120015180519060200120866101400151604051602001613cb79190615306565b60405160208183030381529060405280519060200120876101600151604051602001613ce391906161e5565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16826000015167ffffffffffffffff1614613de15781516040517f1279ec8a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b600b54610140830151517401000000000000000000000000000000000000000090910461ffff161015613e525760608201516040517f099d3f7200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b808261014001515114613ea35760608201516040517f8808f8e700000000000000000000000000000000000000000000000000000000815267ffffffffffffffff909116600482015260240161091f565b600b546101208301515176010000000000000000000000000000000000000000000090910463ffffffff161015610d7b57600b54610120830151516040517f8693378900000000000000000000000000000000000000000000000000000000815276010000000000000000000000000000000000000000000090920463ffffffff166004830152602482015260440161091f565b6000818310613f4657816112c0565b5090919050565b6000613f79827f01ffc9a700000000000000000000000000000000000000000000000000000000613fb1565b80156108ac5750613faa827fffffffff00000000000000000000000000000000000000000000000000000000613fb1565b1592915050565b604080517fffffffff000000000000000000000000000000000000000000000000000000008316602480830191909152825180830390910181526044909101909152602080820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a700000000000000000000000000000000000000000000000000000000178152825160009392849283928392918391908a617530fa92503d91506000519050828015614069575060208210155b80156140755750600081115b979650505050505050565b60006112c08383614580565b6000818152600283016020526040812054801515806140b057506140b08484614080565b6112c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640161091f565b600081815260028301602052604081208190556112c08383614598565b60008281526002840160205260408120829055611c5884846145a4565b600081815260028301602052604081205481908061417f576141728585614080565b9250600091506111a29050565b6001925090506111a2565b60006108ac826145b0565b600080806141a385856145ba565b600081815260029690960160205260409095205494959350505050565b6000670de0b6b3a76400006141f3837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff861661587a565b6112c091906161f8565b825474010000000000000000000000000000000000000000900460ff161580614224575081155b1561422e57505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061427490700100000000000000000000000000000000900463ffffffff1642615811565b9050801561433457818311156142b6576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546142f09083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166139ab565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156143eb5773ffffffffffffffffffffffffffffffffffffffff8416614393576040517ff94ebcd1000000000000000000000000000000000000000000000000000000008152600481018390526024810186905260440161091f565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff8516604482015260640161091f565b848310156144fe5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061442f9082615811565b614439878a615811565b6144439190615a1f565b61444d91906161f8565b905073ffffffffffffffffffffffffffffffffffffffff86166144a6576040517f15279c08000000000000000000000000000000000000000000000000000000008152600481018290526024810186905260440161091f565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff8716604482015260640161091f565b6145088584615811565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600081815260018301602052604081205415156112c0565b60006112c083836145c6565b60006112c083836146c0565b60006108ac825490565b60006112c0838361470f565b600081815260018301602052604081205480156146af5760006145ea600183615811565b85549091506000906145fe90600190615811565b905081811461466357600086600001828154811061461e5761461e6158b8565b9060005260206000200154905080876000018481548110614641576146416158b8565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806146745761467461620c565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506108ac565b60009150506108ac565b5092915050565b6000818152600183016020526040812054614707575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556108ac565b5060006108ac565b6000826000018281548110614726576147266158b8565b9060005260206000200154905092915050565b8280548282559060005260206000209081019282156147b3579160200282015b828111156147b357825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190614759565b506113eb9291505b808211156113eb57600081556001016147bb565b60c081016108ac828473ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b67ffffffffffffffff81168114611d1757600080fd5b803561486181614840565b919050565b60006020828403121561487857600080fd5b81356112c081614840565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b600481106148e9577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9052565b602081016108ac82846148b2565b60005b838110156149165781810151838201526020016148fe565b50506000910152565b600081518084526149378160208601602086016148fb565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006112c0602083018461491f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff811182821017156149ce576149ce61497c565b60405290565b6040516101a0810167ffffffffffffffff811182821017156149ce576149ce61497c565b6040516080810167ffffffffffffffff811182821017156149ce576149ce61497c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614a6257614a6261497c565b604052919050565b600067ffffffffffffffff821115614a8457614a8461497c565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611d1757600080fd5b803561486181614a8e565b600082601f830112614acc57600080fd5b81356020614ae1614adc83614a6a565b614a1b565b82815260059290921b84018101918181019086841115614b0057600080fd5b8286015b84811015614b24578035614b1781614a8e565b8352918301918301614b04565b509695505050505050565b803560ff8116811461486157600080fd5b600067ffffffffffffffff821115614b5a57614b5a61497c565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112614b9757600080fd5b8135614ba5614adc82614b40565b818152846020838601011115614bba57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c08789031215614bf057600080fd5b863567ffffffffffffffff80821115614c0857600080fd5b614c148a838b01614abb565b97506020890135915080821115614c2a57600080fd5b614c368a838b01614abb565b9650614c4460408a01614b2f565b95506060890135915080821115614c5a57600080fd5b614c668a838b01614b86565b9450614c7460808a01614856565b935060a0890135915080821115614c8a57600080fd5b50614c9789828a01614b86565b9150509295509295509295565b60008060408385031215614cb757600080fd5b8235614cc281614840565b9150602083013560048110614cd657600080fd5b809150509250929050565b60008083601f840112614cf357600080fd5b50813567ffffffffffffffff811115614d0b57600080fd5b6020830191508360208260061b85010111156111a257600080fd5b60008060008060408587031215614d3c57600080fd5b843567ffffffffffffffff80821115614d5457600080fd5b614d6088838901614ce1565b90965094506020870135915080821115614d7957600080fd5b50614d8687828801614ce1565b95989497509550505050565b8015158114611d1757600080fd5b803561486181614d92565b600082601f830112614dbc57600080fd5b81356020614dcc614adc83614a6a565b82815260069290921b84018101918181019086841115614deb57600080fd5b8286015b84811015614b245760408189031215614e085760008081fd5b614e106149ab565b8135614e1b81614a8e565b81528185013585820152835291830191604001614def565b6000614e41614adc84614a6a565b8381529050602080820190600585901b840186811115614e6057600080fd5b845b81811015614e9c57803567ffffffffffffffff811115614e825760008081fd5b614e8e89828901614b86565b855250928201928201614e62565b505050509392505050565b600082601f830112614eb857600080fd5b6112c083833560208501614e33565b60006101a08284031215614eda57600080fd5b614ee26149d4565b9050614eed82614856565b8152614efb60208301614ab0565b6020820152614f0c60408301614ab0565b6040820152614f1d60608301614856565b606082015260808201356080820152614f3860a08301614da0565b60a0820152614f4960c08301614856565b60c0820152614f5a60e08301614ab0565b60e082015261010082810135908201526101208083013567ffffffffffffffff80821115614f8757600080fd5b614f9386838701614b86565b83850152610140925082850135915080821115614faf57600080fd5b614fbb86838701614dab565b83850152610160925082850135915080821115614fd757600080fd5b50614fe485828601614ea7565b82840152505061018080830135818301525092915050565b6000806040838503121561500f57600080fd5b823567ffffffffffffffff8082111561502757600080fd5b61503386838701614ec7565b9350602085013591508082111561504957600080fd5b5061505685828601614ea7565b9150509250929050565b61506a81846148b2565b604060208201526000611c58604083018461491f565b60006020828403121561509257600080fd5b81356112c081614a8e565b600081518084526020808501945080840160005b838110156150e357815173ffffffffffffffffffffffffffffffffffffffff16875295820195908201906001016150b1565b509495945050505050565b6020815260006112c0602083018461509d565b6020808252825182820181905260009190848201906040850190845b8181101561514f57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161511d565b50909695505050505050565b60008083601f84011261516d57600080fd5b50813567ffffffffffffffff81111561518557600080fd5b6020830191508360208285010111156111a257600080fd5b60008083601f8401126151af57600080fd5b50813567ffffffffffffffff8111156151c757600080fd5b6020830191508360208260051b85010111156111a257600080fd5b60008060008060008060008060a0898b0312156151fe57600080fd5b883567ffffffffffffffff8082111561521657600080fd5b6152228c838d01614dab565b995060208b013591508082111561523857600080fd5b6152448c838d0161515b565b909950975060408b0135915061525982614a8e565b90955060608a0135908082111561526f57600080fd5b61527b8c838d0161519d565b909650945060808b013591508082111561529457600080fd5b506152a18b828c0161519d565b999c989b5096995094979396929594505050565b600081518084526020808501945080840160005b838110156150e3578151805173ffffffffffffffffffffffffffffffffffffffff16885283015183880152604090960195908201906001016152c9565b6020815260006112c060208301846152b5565b600082601f83011261532a57600080fd5b8135602061533a614adc83614a6a565b82815260059290921b8401810191818101908684111561535957600080fd5b8286015b84811015614b2457803567ffffffffffffffff81111561537d5760008081fd5b61538b8986838b0101614ea7565b84525091830191830161535d565b600082601f8301126153aa57600080fd5b813560206153ba614adc83614a6a565b82815260059290921b840181019181810190868411156153d957600080fd5b8286015b84811015614b2457803583529183019183016153dd565b60006080828403121561540657600080fd5b61540e6149f8565b9050813567ffffffffffffffff8082111561542857600080fd5b818401915084601f83011261543c57600080fd5b8135602061544c614adc83614a6a565b82815260059290921b8401810191818101908884111561546b57600080fd5b8286015b848110156154a3578035868111156154875760008081fd5b6154958b86838b0101614ec7565b84525091830191830161546f565b50865250858101359350828411156154ba57600080fd5b6154c687858801615319565b908501525060408401359150808211156154df57600080fd5b506154ec84828501615399565b6040830152506060820135606082015292915050565b6000806040838503121561551557600080fd5b823567ffffffffffffffff8082111561552d57600080fd5b615539868387016153f4565b935060209150818501358181111561555057600080fd5b85019050601f8101861361556357600080fd5b8035615571614adc82614a6a565b81815260059190911b8201830190838101908883111561559057600080fd5b928401925b828410156155ae57833582529284019290840190615595565b80955050505050509250929050565b60a081016108ac828463ffffffff808251168352602082015173ffffffffffffffffffffffffffffffffffffffff8082166020860152806040850151166040860152505061ffff6060830151166060840152806080830151166080840152505050565b60006020828403121561563257600080fd5b813567ffffffffffffffff81111561564957600080fd5b820160a081850312156112c057600080fd5b60008060008060008060008060e0898b03121561567757600080fd5b606089018a81111561568857600080fd5b8998503567ffffffffffffffff808211156156a257600080fd5b6156ae8c838d0161515b565b909950975060808b01359150808211156156c757600080fd5b6156d38c838d0161519d565b909750955060a08b01359150808211156156ec57600080fd5b506156f98b828c0161519d565b999c989b50969995989497949560c00135949350505050565b6000806020838503121561572557600080fd5b823567ffffffffffffffff81111561573c57600080fd5b6157488582860161515b565b90969095509350505050565b80356fffffffffffffffffffffffffffffffff8116811461486157600080fd5b60006060828403121561578657600080fd5b6040516060810181811067ffffffffffffffff821117156157a9576157a961497c565b60405282356157b781614d92565b81526157c560208401615754565b60208201526157d660408401615754565b60408201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156108ac576108ac6157e2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061586e5761586e615824565b92169190910692915050565b80820281158282048414176108ac576108ac6157e2565b600067ffffffffffffffff808416806158ac576158ac615824565b92169190910492915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203615918576159186157e2565b5060010190565b600063ffffffff808316818103615938576159386157e2565b6001019392505050565b600061012063ffffffff808d1684528b6020850152808b166040850152508060608401526159728184018a61509d565b90508281036080840152615986818961509d565b905060ff871660a084015282810360c08401526159a3818761491f565b905067ffffffffffffffff851660e08401528281036101008401526159c8818561491f565b9c9b505050505050505050505050565b6000602082840312156159ea57600080fd5b81516112c081614a8e565b60006112c0368484614e33565b600060208284031215615a1457600080fd5b81516112c081614840565b808201808211156108ac576108ac6157e2565b608081528451608082015267ffffffffffffffff60208601511660a08201526000604086015160a060c0840152615a6d61012084018261491f565b905060608701517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80808584030160e0860152615aa9838361491f565b925060808901519150808584030161010086015250615ac882826152b5565b92505050615adc602083018661ffff169052565b836040830152612b15606083018473ffffffffffffffffffffffffffffffffffffffff169052565b60008060408385031215615b1757600080fd5b8251615b2281614d92565b602084015190925067ffffffffffffffff811115615b3f57600080fd5b8301601f81018513615b5057600080fd5b8051615b5e614adc82614b40565b818152866020838501011115615b7357600080fd5b615b848260208301602086016148fb565b8093505050509250929050565b805163ffffffff8116811461486157600080fd5b600060a08284031215615bb757600080fd5b60405160a0810181811067ffffffffffffffff82111715615bda57615bda61497c565b604052615be683615b91565b81526020830151615bf681614a8e565b60208201526040830151615c0981614a8e565b6040820152606083015161ffff81168114615c2357600080fd5b6060820152615c3460808401615b91565b60808201529392505050565b6101608101615cb2828573ffffffffffffffffffffffffffffffffffffffff808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015250508060608301511660608401528060808301511660808401528060a08301511660a0840152505050565b825163ffffffff90811660c0840152602084015173ffffffffffffffffffffffffffffffffffffffff90811660e0850152604085015116610100840152606084015161ffff166101208401526080840151166101408301526112c0565b60006101208b835273ffffffffffffffffffffffffffffffffffffffff8b16602084015267ffffffffffffffff808b166040850152816060850152615d568285018b61509d565b91508382036080850152615d6a828a61509d565b915060ff881660a085015283820360c0850152615d87828861491f565b90861660e085015283810361010085015290506159c8818561491f565b6000815180845260208085019450848260051b860182860160005b85811015615de9578383038952615dd783835161491f565b98850198925090840190600101615dbf565b5090979650505050505050565b60408152615e1160408201845167ffffffffffffffff169052565b60006020840151615e3a606084018273ffffffffffffffffffffffffffffffffffffffff169052565b50604084015173ffffffffffffffffffffffffffffffffffffffff8116608084015250606084015167ffffffffffffffff811660a084015250608084015160c083015260a084015180151560e08401525060c0840151610100615ea88185018367ffffffffffffffff169052565b60e08601519150610120615ed38186018473ffffffffffffffffffffffffffffffffffffffff169052565b81870151925061014091508282860152808701519250506101a06101608181870152615f036101e087018561491f565b93508288015192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0610180818887030181890152615f4286866152b5565b9550828a01519450818887030184890152615f5d8686615da4565b9550808a01516101c089015250505050508281036020840152612b158185615da4565b6000815160208301517fffffffff0000000000000000000000000000000000000000000000000000000080821693506004831015615fc85780818460040360031b1b83161693505b505050919050565b604081526000615fe3604083018561491f565b8281036020840152612b15818561491f565b60a08152600061600860a083018861491f565b73ffffffffffffffffffffffffffffffffffffffff8716602084015285604084015267ffffffffffffffff85166060840152828103608084015261604c818561491f565b98975050505050505050565b60006020828403121561606a57600080fd5b81516112c081614d92565b600081518084526020808501945080840160005b838110156150e357815187529582019590820190600101616089565b6060815260006160b86060830186616075565b82810360208401526160ca8186616075565b915050826040830152949350505050565b6000602082840312156160ed57600080fd5b5051919050565b67ffffffffffffffff8181168382160190808211156146b9576146b96157e2565b67ffffffffffffffff83168152604081016112c060208301846148b2565b600067ffffffffffffffff808316818103615938576159386157e2565b60006020828403121561616257600080fd5b813567ffffffffffffffff81111561617957600080fd5b611c58848285016153f4565b60006040828403121561619757600080fd5b61619f6149ab565b82517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146161cb57600080fd5b81526161d960208401615b91565b60208201529392505050565b6020815260006112c06020830184615da4565b60008261620757616207615824565b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var EVM2EVMOffRampHelperABI = EVM2EVMOffRampHelperMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go index 7ebccb47d4..d21ae3c11e 100644 --- a/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go +++ b/core/gethwrappers/ccip/generated/evm_2_evm_onramp/evm_2_evm_onramp.go @@ -57,22 +57,18 @@ type EVM2EVMOnRampDynamicConfig struct { } type EVM2EVMOnRampFeeTokenConfig struct { - NetworkFeeUSD uint32 - MinTokenTransferFeeUSD uint32 - MaxTokenTransferFeeUSD uint32 - GasMultiplier uint64 - PremiumMultiplier uint64 - Enabled bool + NetworkFeeUSD uint32 + GasMultiplier uint64 + PremiumMultiplier uint64 + Enabled bool } type EVM2EVMOnRampFeeTokenConfigArgs struct { - Token common.Address - NetworkFeeUSD uint32 - MinTokenTransferFeeUSD uint32 - MaxTokenTransferFeeUSD uint32 - GasMultiplier uint64 - PremiumMultiplier uint64 - Enabled bool + Token common.Address + NetworkFeeUSD uint32 + GasMultiplier uint64 + PremiumMultiplier uint64 + Enabled bool } type EVM2EVMOnRampNopAndWeight struct { @@ -91,6 +87,8 @@ type EVM2EVMOnRampStaticConfig struct { } type EVM2EVMOnRampTokenTransferFeeConfig struct { + MinFeeUSD uint32 + MaxFeeUSD uint32 Ratio uint16 DestGasOverhead uint32 DestBytesOverhead uint32 @@ -98,6 +96,8 @@ type EVM2EVMOnRampTokenTransferFeeConfig struct { type EVM2EVMOnRampTokenTransferFeeConfigArgs struct { Token common.Address + MinFeeUSD uint32 + MaxFeeUSD uint32 Ratio uint16 DestGasOverhead uint32 DestBytesOverhead uint32 @@ -139,8 +139,8 @@ type RateLimiterTokenBucket struct { } var EVM2EVMOnRampMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"tokensAndPools\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"minTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"minTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"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\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"minTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"minTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxTokenTransferFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"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\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101806040523480156200001257600080fd5b50604051620083be380380620083be833981016040819052620000359162001e1d565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c08162000323565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555086516001600160a01b0316158062000169575060208701516001600160401b0316155b8062000180575060408701516001600160401b0316155b8062000197575060608701516001600160401b0316155b80620001ae575060c08701516001600160a01b0316155b15620001cd576040516306b7c75960e31b815260040160405180910390fd5b6020808801516040808a015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815289516001600160a01b0390811660e052928a01516001600160401b0390811661010052918a015182166101205260608a015190911660a0908152908901516001600160601b031660c0908152908901518216610140528801511661016052620002aa86620003ce565b620002b58362000645565b620002c082620007e0565b620002cb81620008e5565b6040805160008082526020820190925262000316916200030e565b6040805180820190915260008082526020820152815260200190600190039081620002e65790505b508662000b0f565b5050505050505062002408565b336001600160a01b038216036200037d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003fa576040516306b7c75960e31b815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055509050507f2a57f7c2027cf032c78b77d4d8d2fbd20ad22e5d5e5b5fb23ac7d7820d44adc66040518060e0016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b0316815250826040516200063a92919062001ff2565b60405180910390a150565b60005b8151811015620007ae57600082828151811062000669576200066962002072565b6020908102919091018101516040805160c080820183528385015163ffffffff908116835283850151811683870190815260608087015183168587019081526080808901516001600160401b0390811693880193845260a0808b01518216928901928352968a0151151596880196875298516001600160a01b03166000908152600d909a529690982094518554925198519151965194511515600160e01b0260ff60e01b19958916600160a01b0295909516600160a01b600160e81b0319979098166c0100000000000000000000000002600160601b600160a01b0319928516680100000000000000000292909216600160401b600160a01b0319998516640100000000026001600160401b0319909416919094161791909117969096161794909417919091169190911791909117905550620007a6816200209e565b905062000648565b507f2386f61ab5cafc3fed44f9f614f721ab53479ef64067fd16c1a2491b63ddf1a8816040516200063a9190620020ba565b60005b8151811015620008b357600082828151811062000804576200080462002072565b60209081029190910181015160408051606080820183528385015161ffff90811683528385015163ffffffff90811684880190815292860151811684860190815295516001600160a01b03166000908152600e909752939095209151825491519451841666010000000000000263ffffffff60301b1995909416620100000265ffffffffffff19909216951694909417939093179190911617905550620008ab816200209e565b9050620007e3565b507f3df02211160f78e9bbed13e8bf0752035362a05f0651a5e25007acfb659c3620816040516200063a919062002172565b805160408111156200090a57604051635ad0867d60e11b815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff161580159062000954575060105463ffffffff6c010000000000000000000000008204166001600160601b0390911610155b1562000964576200096462000e12565b600062000972600762001012565b90505b8015620009be576000620009986200098f600184620021e1565b60079062001025565b509050620009a860078262001043565b505080620009b690620021f7565b905062000975565b506000805b8281101562000aa6576000848281518110620009e357620009e362002072565b6020026020010151600001519050600085838151811062000a085762000a0862002072565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000a4057506001600160a01b038216155b1562000a6b57604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000a7d60078361ffff841662001061565b5062000a8e61ffff82168562002211565b935050508062000a9e906200209e565b9050620009c3565b506010805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000b02908390869062002231565b60405180910390a1505050565b60005b825181101562000c4b57600083828151811062000b335762000b3362002072565b6020026020010151600001519050600084838151811062000b585762000b5862002072565b6020908102919091018101510151905062000b75600a8362001081565b62000b9f576040516373913ebd60e01b81526001600160a01b038316600482015260240162000084565b6001600160a01b03811662000bb6600a8462001098565b6001600160a01b03161462000bde57604051630d98f73360e31b815260040160405180910390fd5b62000beb600a83620010af565b1562000c3557604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b50508062000c43906200209e565b905062000b12565b5060005b815181101562000e0d57600082828151811062000c705762000c7062002072565b6020026020010151600001519050600083838151811062000c955762000c9562002072565b602002602001015160200151905060006001600160a01b0316826001600160a01b0316148062000ccc57506001600160a01b038116155b1562000cea5760405162d8548360e71b815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d29573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d4f91906200229e565b6001600160a01b0316826001600160a01b03161462000d8157604051630d98f73360e31b815260040160405180910390fd5b62000d8f600a8383620010c6565b1562000dde57604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a162000df7565b604051633caf458560e01b815260040160405180910390fd5b50508062000e05906200209e565b905062000c4f565b505050565b6000546001600160a01b0316331480159062000e3957506002546001600160a01b03163314155b801562000e50575062000e4e600733620010de565b155b1562000e6f5760405163032bb72b60e31b815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff16600081900362000eab5760405163990e30bf60e01b815260040160405180910390fd5b6010546001600160601b03168181101562000ed9576040516311a1ee3b60e31b815260040160405180910390fd5b600062000ee5620010f5565b121562000f0557604051631e9acf1760e31b815260040160405180910390fd5b80600062000f14600762001012565b905060005b8181101562000fec5760008062000f3260078462001025565b909250905060008762000f4f836001600160601b038a16620022be565b62000f5b9190620022d8565b905062000f698187620022fb565b60e05190965062000f8e906001600160a01b0316846001600160601b03841662001183565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a25050508062000fe4906200209e565b905062000f19565b5050601080546001600160601b0319166001600160601b03929092169190911790555050565b60006200101f82620011db565b92915050565b6000808080620010368686620011e8565b9097909650945050505050565b60006200105a836001600160a01b03841662001215565b9392505050565b600062001079846001600160a01b0385168462001234565b949350505050565b60006200105a836001600160a01b03841662001253565b60006200105a836001600160a01b03841662001261565b60006200105a836001600160a01b0384166200126f565b600062001079846001600160a01b038516846200127d565b60006200105a836001600160a01b03841662001295565b60105460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa1580156200114c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200117291906200231e565b6200117e919062002338565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000e0d918591620012a316565b60006200101f8262001374565b60008080620011f885856200137f565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081208190556200105a83836200138d565b600082815260028401602052604081208290556200107984846200139b565b60006200105a838362001295565b60006200105a8383620013a9565b60006200105a838362001215565b60006200107984846001600160a01b03851662001234565b60006200105a83836200141e565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620012f2906001600160a01b03851690849062001437565b80519091501562000e0d57808060200190518101906200131391906200235b565b62000e0d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b60006200101f825490565b60006200105a838362001448565b60006200105a838362001475565b60006200105a838362001580565b600081815260028301602052604081205480151580620013d05750620013d0848462001295565b6200105a5760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640162000084565b600081815260018301602052604081205415156200105a565b6060620010798484600085620015d2565b600082600001828154811062001462576200146262002072565b9060005260206000200154905092915050565b600081815260018301602052604081205480156200156e5760006200149c600183620021e1565b8554909150600090620014b290600190620021e1565b90508181146200151e576000866000018281548110620014d657620014d662002072565b9060005260206000200154905080876000018481548110620014fc57620014fc62002072565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062001532576200153262002379565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200101f565b60009150506200101f565b5092915050565b6000818152600183016020526040812054620015c9575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200101f565b5060006200101f565b606082471015620016355760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620016539190620023b5565b60006040518083038185875af1925050503d806000811462001692576040519150601f19603f3d011682016040523d82523d6000602084013e62001697565b606091505b509092509050620016ab87838387620016b6565b979650505050505050565b606083156200172a57825160000362001722576001600160a01b0385163b620017225760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162001079565b620010798383815115620017415781518083602001fd5b8060405162461bcd60e51b8152600401620000849190620023d3565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b03811182821017156200179857620017986200175d565b60405290565b60405161014081016001600160401b03811182821017156200179857620017986200175d565b604080519081016001600160401b03811182821017156200179857620017986200175d565b604051608081016001600160401b03811182821017156200179857620017986200175d565b604051601f8201601f191681016001600160401b03811182821017156200183957620018396200175d565b604052919050565b6001600160a01b03811681146200185757600080fd5b50565b8051620018678162001841565b919050565b80516001600160401b03811681146200186757600080fd5b600060e082840312156200189757600080fd5b620018a162001773565b90508151620018b08162001841565b8152620018c0602083016200186c565b6020820152620018d3604083016200186c565b6040820152620018e6606083016200186c565b606082015260808201516001600160601b03811681146200190657600080fd5b60808201526200191960a083016200185a565b60a08201526200192c60c083016200185a565b60c082015292915050565b805161ffff811681146200186757600080fd5b805163ffffffff811681146200186757600080fd5b600061014082840312156200197357600080fd5b6200197d6200179e565b90506200198a826200185a565b81526200199a6020830162001937565b6020820152620019ad604083016200194a565b6040820152620019c06060830162001937565b6060820152620019d3608083016200194a565b6080820152620019e660a0830162001937565b60a0820152620019f960c0830162001937565b60c082015262001a0c60e083016200185a565b60e082015261010062001a218184016200194a565b9082015261012062001a358382016200194a565b9082015292915050565b60006001600160401b0382111562001a5b5762001a5b6200175d565b5060051b60200190565b600082601f83011262001a7757600080fd5b8151602062001a9062001a8a8362001a3f565b6200180e565b82815260069290921b8401810191818101908684111562001ab057600080fd5b8286015b8481101562001b0a576040818903121562001acf5760008081fd5b62001ad9620017c4565b815162001ae68162001841565b81528185015162001af78162001841565b8186015283529183019160400162001ab4565b509695505050505050565b805180151581146200186757600080fd5b80516001600160801b03811681146200186757600080fd5b60006060828403121562001b5157600080fd5b604051606081016001600160401b038111828210171562001b765762001b766200175d565b60405290508062001b878362001b15565b815262001b976020840162001b26565b602082015262001baa6040840162001b26565b60408201525092915050565b600082601f83011262001bc857600080fd5b8151602062001bdb62001a8a8362001a3f565b82815260e0928302850182019282820191908785111562001bfb57600080fd5b8387015b8581101562001cb05781818a03121562001c195760008081fd5b62001c2362001773565b815162001c308162001841565b815262001c3f8287016200194a565b86820152604062001c528184016200194a565b90820152606062001c658382016200194a565b90820152608062001c788382016200186c565b9082015260a062001c8b8382016200186c565b9082015260c062001c9e83820162001b15565b90820152845292840192810162001bff565b5090979650505050505050565b600082601f83011262001ccf57600080fd5b8151602062001ce262001a8a8362001a3f565b82815260079290921b8401810191818101908684111562001d0257600080fd5b8286015b8481101562001b0a576080818903121562001d215760008081fd5b62001d2b620017e9565b815162001d388162001841565b815262001d4782860162001937565b85820152604062001d5a8184016200194a565b90820152606062001d6d8382016200194a565b9082015283529183019160800162001d06565b600082601f83011262001d9257600080fd5b8151602062001da562001a8a8362001a3f565b82815260069290921b8401810191818101908684111562001dc557600080fd5b8286015b8481101562001b0a576040818903121562001de45760008081fd5b62001dee620017c4565b815162001dfb8162001841565b815262001e0a82860162001937565b8186015283529183019160400162001dc9565b6000806000806000806000610300888a03121562001e3a57600080fd5b62001e46898962001884565b965062001e578960e08a016200195f565b6102208901519096506001600160401b038082111562001e7657600080fd5b62001e848b838c0162001a65565b965062001e968b6102408c0162001b3e565b95506102a08a015191508082111562001eae57600080fd5b62001ebc8b838c0162001bb6565b94506102c08a015191508082111562001ed457600080fd5b62001ee28b838c0162001cbd565b93506102e08a015191508082111562001efa57600080fd5b5062001f098a828b0162001d80565b91505092959891949750929550565b80516001600160a01b03168252602081015162001f3b602084018261ffff169052565b50604081015162001f54604084018263ffffffff169052565b50606081015162001f6b606084018261ffff169052565b50608081015162001f84608084018263ffffffff169052565b5060a081015162001f9b60a084018261ffff169052565b5060c081015162001fb260c084018261ffff169052565b5060e081015162001fce60e08401826001600160a01b03169052565b506101008181015163ffffffff908116918401919091526101209182015116910152565b82516001600160a01b0390811682526020808501516001600160401b0390811691840191909152604080860151821690840152606080860151909116908301526080808501516001600160601b03169083015260a08085015182169083015260c0808501519091169082015261022081016200105a60e083018462001f18565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620020b357620020b362002088565b5060010190565b602080825282518282018190526000919060409081850190868401855b828110156200216557815180516001600160a01b031685528681015163ffffffff9081168887015286820151811687870152606080830151909116908601526080808201516001600160401b03169086015260a08082015162002144878301826001600160401b03169052565b505060c09081015115159085015260e09093019290850190600101620020d7565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156200216557815180516001600160a01b031685528681015161ffff16878601528581015163ffffffff908116878701526060918201511690850152608090930192908501906001016200218f565b818103818111156200101f576200101f62002088565b60008162002209576200220962002088565b506000190190565b63ffffffff81811683821601908082111562001579576200157962002088565b6000604080830163ffffffff8616845260208281860152818651808452606087019150828801935060005b818110156200229057845180516001600160a01b0316845284015161ffff168484015293830193918501916001016200225c565b509098975050505050505050565b600060208284031215620022b157600080fd5b81516200105a8162001841565b80820281158282048414176200101f576200101f62002088565b600082620022f657634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b0382811682821603908082111562001579576200157962002088565b6000602082840312156200233157600080fd5b5051919050565b818103600083128015838313168383128216171562001579576200157962002088565b6000602082840312156200236e57600080fd5b6200105a8262001b15565b634e487b7160e01b600052603160045260246000fd5b60005b83811015620023ac57818101518382015260200162002392565b50506000910152565b60008251620023c98184602087016200238f565b9190910192915050565b6020815260008251806020840152620023f48160408501602087016200238f565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516101405161016051615eaf6200250f600039600081816103340152818161151d0152613e730152600081816103050152818161143f015281816114a701528181611a8601528181611aee0152613e4401526000818161027101528181610bc201528181611e830152613db001526000818161024101528181611bb90152613d8001526000818161021201528181610f910152818161183101528181611932015281816123b40152818161313f015281816134cc0152613d510152600081816102d1015281816119fe0152613e100152600081816102a1015281816126fb0152613de001526000611f4b0152615eaf6000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806375294130116100f9578063b06d41bc11610097578063d3c7c2c711610071578063d3c7c2c71461092c578063e687b40a14610941578063eff7cc4814610954578063f2fde38b1461095c57600080fd5b8063b06d41bc146108fb578063c92b283214610911578063d09dc3391461092457600080fd5b8063856c8247116100d3578063856c8247146107575780638da5cb5b1461076a5780639a113c361461077b578063a7d3e02f146108e857600080fd5b8063752941301461072957806376f6ae761461073c57806379ba50971461074f57600080fd5b8063546719cd11610166578063599f643111610140578063599f64311461056f5780635d86f14114610594578063704b6c02146105a75780637437ff9f146105ba57600080fd5b8063546719cd146104d8578063549e946f1461053c57806354b714681461054f57600080fd5b8063352e4bc8116101a2578063352e4bc81461046e57806338724a95146104835780633a87ac53146104a45780634120fccd146104b757600080fd5b806306285c69146101c95780631772047e1461037a578063181f5a7714610425575b600080fd5b6103646040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b604051610371919061499c565b60405180910390f35b6103f1610388366004614a3d565b6040805160608082018352600080835260208084018290529284018190526001600160a01b03949094168452600e825292829020825193840183525461ffff8116845263ffffffff62010000820481169285019290925266010000000000009004169082015290565b60408051825161ffff16815260208084015163ffffffff908116918301919091529282015190921690820152606001610371565b6104616040518060400160405280601381526020017f45564d3245564d4f6e52616d7020312e322e300000000000000000000000000081525081565b6040516103719190614ac8565b61048161047c366004614c67565b61096f565b005b610496610491366004614d9d565b6109d8565b604051908152602001610371565b6104816104b2366004614e6e565b610e38565b6104bf610e4e565b60405167ffffffffffffffff9091168152602001610371565b6104e0610e82565b604051610371919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b61048161054a366004614ed2565b610f32565b6010546040516bffffffffffffffffffffffff9091168152602001610371565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610371565b61057c6105a2366004614a3d565b6110e7565b6104816105b5366004614a3d565b611146565b61071c6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101919091525060408051610140810182526005546001600160a01b03808216835261ffff7401000000000000000000000000000000000000000083048116602085015263ffffffff76010000000000000000000000000000000000000000000084048116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000810490911660c0850152640100000000810490911660e08401527801000000000000000000000000000000000000000000000000810484166101008401520490911661012082015290565b6040516103719190614fe6565b610481610737366004615007565b611210565b61048161074a3660046150f4565b611276565b61048161132e565b6104bf610765366004614a3d565b611411565b6000546001600160a01b031661057c565b61087e610789366004614a3d565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810191909152506001600160a01b03166000908152600d6020908152604091829020825160c081018452905463ffffffff808216835264010000000082048116938301939093526801000000000000000081049092169281019290925267ffffffffffffffff6c0100000000000000000000000082048116606084015274010000000000000000000000000000000000000000820416608083015260ff7c010000000000000000000000000000000000000000000000000000000090910416151560a082015290565b6040516103719190600060c08201905063ffffffff80845116835280602085015116602084015280604085015116604084015250606083015167ffffffffffffffff8082166060850152806080860151166080850152505060a0830151151560a083015292915050565b6104966108f6366004615169565b611519565b610903611fbd565b604051610371929190615217565b61048161091f366004615259565b6120c1565b610496612129565b610934612133565b60405161037191906152c7565b61048161094f366004615314565b6121e4565b6104816121f5565b61048161096a366004614a3d565b61248c565b6000546001600160a01b0316331480159061099557506002546001600160a01b03163314155b156109cc576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109d58161249d565b50565b6000806109f06109eb60808501856153dc565b6126cc565b9050610a1b610a0260208501856153dc565b8351909150610a146040870187615441565b90506127c0565b6000600d81610a306080870160608801614a3d565b6001600160a01b031681526020808201929092526040908101600020815160c081018352905463ffffffff80821683526401000000008204811694830194909452680100000000000000008104909316918101919091526c01000000000000000000000000820467ffffffffffffffff90811660608301527401000000000000000000000000000000000000000083041660808201527c010000000000000000000000000000000000000000000000000000000090910460ff16151560a08201819052909150610b4d57610b0a6080850160608601614a3d565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024015b60405180910390fd5b600654600090819064010000000090046001600160a01b031663ffdb4b37610b7b6080890160608a01614a3d565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044016040805180830381865afa158015610c06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2a91906154d5565b9092509050806000808080610c4260408c018c615441565b90501115610c7d57610c71610c5d60808c0160608d01614a3d565b87610c6b60408e018e615441565b8b6128e9565b91945092509050610c99565b8651610c969063ffffffff16662386f26fc10000615537565b92505b6080870151610cb29067ffffffffffffffff1684615537565b606088015160055491945060009167ffffffffffffffff9091169063ffffffff8516907a010000000000000000000000000000000000000000000000000000900461ffff16610d0460208f018f6153dc565b610d0f929150615537565b6005548c51610d3e91760100000000000000000000000000000000000000000000900463ffffffff169061554e565b610d48919061554e565b610d52919061554e565b610d5c9190615537565b610d76906dffffffffffffffffffffffffffff8716615537565b60065490915060009062010000900461ffff1615610dea576000607060ff16887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901c9050610de6818e8060200190610dcc91906153dc565b90508f8060400190610dde9190615441565b905087612ba2565b9150505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff881681610e14848861554e565b610e1e919061554e565b610e289190615561565b9c9b505050505050505050505050565b610e40612c74565b610e4a8282612cea565b5050565b601054600090610e7d90700100000000000000000000000000000000900467ffffffffffffffff16600161559c565b905090565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610e7d9061304a565b6000546001600160a01b03163314801590610f5857506002546001600160a01b03163314155b15610f8f576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480610fd657506001600160a01b038116155b1561100d576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006110176130fc565b121561104f576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610e4a9082906001600160a01b038516906370a0823190602401602060405180830381865afa1580156110b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d691906155bd565b6001600160a01b03851691906131bc565b60006110f4600a8361323c565b611135576040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610b44565b611140600a83613251565b92915050565b6000546001600160a01b0316331480159061116c57506002546001600160a01b03163314155b156111a3576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b6000546001600160a01b0316331480159061123657506002546001600160a01b03163314155b1561126d576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109d581613266565b6000546001600160a01b0316331480159061129c57506002546001600160a01b03163314155b156112d3576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e4a8282808060200260200160405190810160405280939291908181526020016000905b8282101561132457611315604083028601368190038101906155d6565b815260200190600101906112f8565b5050505050613393565b6001546001600160a01b031633146113a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610b44565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff168015801561146a57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611140576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa1580156114ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115129190615615565b9392505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611579573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159d9190615632565b156115d4576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038216611614576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b03163314611658576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61166284806153dc565b90506020146116a95761167584806153dc565b6040517f370d875f000000000000000000000000000000000000000000000000000000008152600401610b44929190615698565b60006116b585806153dc565b8101906116c291906156ac565b90506001600160a01b038111806116d95750600a81105b156116e85761167585806153dc565b60006116fa6109eb60808801886153dc565b519050600061170c6040880188615441565b9150611729905061172060208901896153dc565b905083836127c0565b80156118275760005b818110156117aa576117476040890189615441565b82818110611757576117576156c5565b9050604002016020013560000361179a576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6117a3816156f4565b9050611732565b506118276117bb6040890189615441565b808060200260200160405190810160405280939291908181526020016000905b82821015611807576117f86040830286013681900381019061572c565b815260200190600101906117db565b505060065464010000000090046001600160a01b03169250613606915050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166118616080890160608a01614a3d565b6001600160a01b0316036118c557601080548791906000906118929084906bffffffffffffffffffffffff16615766565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055506119ec565b60065464010000000090046001600160a01b03166241e5be6118ed60808a0160608b01614a3d565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018a90527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa158015611979573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061199d91906155bd565b601080546000906119bd9084906bffffffffffffffffffffffff16615766565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b6010546bffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811691161115611a59576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0385166000908152600f602052604090205467ffffffffffffffff16158015611ab157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611ba9576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611b35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b599190615615565b6001600160a01b0386166000908152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b6000604051806101a001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168152602001876001600160a01b03168152602001856001600160a01b0316815260200160108081819054906101000a900467ffffffffffffffff16611c269061578b565b825467ffffffffffffffff9182166101009390930a838102908302199091161790925582526020808301879052600060408085018290526001600160a01b038c168252600f90925290812080546060909401939092611c85911661578b565b825467ffffffffffffffff9182166101009390930a83810292021916179091558152602001611cba60808b0160608c01614a3d565b6001600160a01b03168152602001888152602001898060200190611cde91906153dc565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611d2560408b018b615441565b808060200260200160405190810160405280939291908181526020016000905b82821015611d7157611d626040830286013681900381019061572c565b81526020019060010190611d45565b505050505081526020018367ffffffffffffffff811115611d9457611d94614adb565b604051908082528060200260200182016040528015611dc757816020015b6060815260200190600190039081611db25790505b508152600060209091018190529091505b82811015611f44576000611def60408b018b615441565b83818110611dff57611dff6156c5565b905060400201803603810190611e15919061572c565b9050611e2481600001516110e7565b6001600160a01b0316639687544589611e3d8d806153dc565b60208087015160408051928301815260008352517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b168152611eab959493927f0000000000000000000000000000000000000000000000000000000000000000916004016157b2565b6000604051808303816000875af1158015611eca573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611f10919081019061580a565b8361016001518381518110611f2757611f276156c5565b60200260200101819052505080611f3d906156f4565b9050611dd8565b50611f6f817f00000000000000000000000000000000000000000000000000000000000000006137c1565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd90611fa5908390615955565b60405180910390a16101800151979650505050505050565b6060600080611fcc600761393a565b90508067ffffffffffffffff811115611fe757611fe7614adb565b60405190808252806020026020018201604052801561202c57816020015b60408051808201909152600080825260208201528152602001906001900390816120055790505b50925060005b8181101561209e57600080612048600784613945565b915091506040518060400160405280836001600160a01b031681526020018261ffff16815250868481518110612080576120806156c5565b6020026020010181905250505080612097906156f4565b9050612032565b505060105491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b031633148015906120e757506002546001600160a01b03163314155b1561211e576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109d5600382613963565b6000610e7d6130fc565b60606000612141600a613b3b565b67ffffffffffffffff81111561215957612159614adb565b604051908082528060200260200182016040528015612182578160200160208202803683370190505b50905060005b81518110156121de5761219c600a82613b46565b508282815181106121af576121af6156c5565b60200260200101816001600160a01b03166001600160a01b031681525050806121d7906156f4565b9050612188565b50919050565b6121ec612c74565b6109d581613b55565b6000546001600160a01b0316331480159061221b57506002546001600160a01b03163314155b801561222f575061222d600733613ead565b155b15612266576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff1660008190036122ba576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546bffffffffffffffffffffffff1681811015612305576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061230f6130fc565b1215612347576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806000612354600761393a565b905060005b818110156124495760008061236f600784613945565b909250905060008761238f836bffffffffffffffffffffffff8a16615537565b6123999190615561565b90506123a58187615aa8565b95506123e96001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff84166131bc565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a250505080612442906156f4565b9050612359565b5050601080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b612494612c74565b6109d581613ec2565b60005b815181101561269c5760008282815181106124bd576124bd6156c5565b6020908102919091018101516040805160c080820183528385015163ffffffff9081168352838501518116838701908152606080870151831685870190815260808089015167ffffffffffffffff90811693880193845260a0808b01518216928901928352968a0151151596880196875298516001600160a01b03166000908152600d909a5296909820945185549251985191519651945115157c0100000000000000000000000000000000000000000000000000000000027fffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffff9589167401000000000000000000000000000000000000000002959095167fffffff000000000000000000ffffffffffffffffffffffffffffffffffffffff979098166c01000000000000000000000000027fffffffffffffffffffffffff0000000000000000ffffffffffffffffffffffff9285166801000000000000000002929092167fffffffffffffffffffffffff000000000000000000000000ffffffffffffffff998516640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909416919094161791909117969096161794909417919091169190911791909117905550612695816156f4565b90506124a0565b507f2386f61ab5cafc3fed44f9f614f721ab53479ef64067fd16c1a2491b63ddf1a8816040516112059190615acd565b60408051602081019091526000815260008290036127225750604080516020810190915267ffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152611140565b7f97a657c90000000000000000000000000000000000000000000000000000000061274d8385615b77565b7fffffffff0000000000000000000000000000000000000000000000000000000016146127a6576040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6127b38260048186615bbf565b8101906115129190615be9565b6006547801000000000000000000000000000000000000000000000000900463ffffffff1680841115612829576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101859052604401610b44565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff1683111561288b576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055474010000000000000000000000000000000000000000900461ffff168211156128e3576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000808084815b81811015612b2d57600088888381811061290c5761290c6156c5565b905060400201803603810190612922919061572c565b80516001600160a01b03166000908152600e60209081526040918290208251606081018452905461ffff8116825263ffffffff620100008204811693830193909352660100000000000090048216928101929092528251929350909161298c91600a919061323c16565b6129d05781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610b44565b805160009061ffff1615612ae95760008d6001600160a01b031684600001516001600160a01b031614612a945760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612a69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8d9190615c2b565b9050612a97565b508b5b82516020850151620186a09161ffff1690612ad1907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff851690613f9d565b612adb9190615537565b612ae59190615561565b9150505b612af3818961554e565b9750816020015187612b059190615c46565b9650816040015186612b179190615c46565b955050505080612b26906156f4565b90506128f0565b506000856020015163ffffffff16662386f26fc10000612b4d9190615537565b905080851015612b60579350612b979050565b6000866040015163ffffffff16662386f26fc10000612b7f9190615537565b905080861115612b93579450612b97915050565b5050505b955095509592505050565b60008063ffffffff8316612bb7608086615537565b612bc38761022061554e565b612bcd919061554e565b612bd7919061554e565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff1690612c199061ffff1684615537565b612c23919061554e565b60065490915062010000900461ffff16612c4d6dffffffffffffffffffffffffffff891683615537565b612c579190615537565b612c6790655af3107a4000615537565b925050505b949350505050565b6000546001600160a01b03163314612ce8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610b44565b565b60005b8251811015612e4b576000838281518110612d0a57612d0a6156c5565b60200260200101516000015190506000848381518110612d2c57612d2c6156c5565b6020026020010151602001519050612d4e82600a61323c90919063ffffffff16565b612d8f576040517f73913ebd0000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610b44565b6001600160a01b038116612da4600a84613251565b6001600160a01b031614612de4576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612def600a83613fda565b15612e3857604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b505080612e44906156f4565b9050612ced565b5060005b8151811015613045576000828281518110612e6c57612e6c6156c5565b60200260200101516000015190506000838381518110612e8e57612e8e6156c5565b602002602001015160200151905060006001600160a01b0316826001600160a01b03161480612ec457506001600160a01b038116155b15612efb576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f5d9190615c63565b6001600160a01b0316826001600160a01b031614612fa7576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612fb3600a8383613fef565b1561300057604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a1613032565b6040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50508061303e906156f4565b9050612e4f565b505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526130d882606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426130bc9190615c80565b85608001516fffffffffffffffffffffffffffffffff16614005565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6010546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561318e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131b291906155bd565b610e7d9190615c93565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261304590849061402d565b6000611512836001600160a01b03841661412c565b6000611512836001600160a01b038416614138565b60005b8151811015613363576000828281518110613286576132866156c5565b60209081029190910181015160408051606080820183528385015161ffff90811683528385015163ffffffff90811684880190815292860151811684860190815295516001600160a01b03166000908152600e90975293909520915182549151945184166601000000000000027fffffffffffffffffffffffffffffffffffffffffffff00000000ffffffffffff9590941662010000027fffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000090921695169490941793909317919091161790555061335c816156f4565b9050613269565b507f3df02211160f78e9bbed13e8bf0752035362a05f0651a5e25007acfb659c3620816040516112059190615cb3565b805160408111156133d0576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff161580159061341e575060105463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff90911610155b1561342b5761342b6121f5565b6000613437600761393a565b90505b8015613479576000613458613450600184615c80565b600790613945565b509050613466600782614144565b50508061347290615d20565b905061343a565b506000805b8281101561358757600084828151811061349a5761349a6156c5565b602002602001015160000151905060008583815181106134bc576134bc6156c5565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316148061351157506001600160a01b038216155b15613553576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610b44565b61356360078361ffff8416614159565b5061357261ffff821685615c46565b9350505080613580906156f4565b905061347e565b50601080547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd24906135f99083908690615d55565b60405180910390a1505050565b81516000805b828110156137b3576000846001600160a01b031663d02641a0878481518110613637576136376156c5565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b0390911660048201526024016040805180830381865afa15801561369e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136c29190615d74565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8116600003613747578582815181106136fd576136fd6156c5565b6020908102919091010151516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610b44565b61379586838151811061375c5761375c6156c5565b602002602001015160200151827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16613f9d90919063ffffffff16565b61379f908461554e565b925050806137ac906156f4565b905061360c565b506128e3600382600061416f565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001516040516020016138579897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b60405160208183030381529060405280519060200120856101200151805190602001208661014001516040516020016138909190615da7565b604051602081830303815290604052805190602001208761016001516040516020016138bc9190615dba565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b6000611140826144be565b600080808061395486866144c9565b909450925050505b9250929050565b815460009061398c90700100000000000000000000000000000000900463ffffffff1642615c80565b90508015613a2e57600183015483546139d4916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416614005565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354613a54916fffffffffffffffffffffffffffffffff90811691166144f4565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906135f99084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b60006111408261393a565b60008080806139548686613945565b60e08101516001600160a01b0316613b99576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055509050507f2a57f7c2027cf032c78b77d4d8d2fbd20ad22e5d5e5b5fb23ac7d7820d44adc66040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681525082604051611205929190615dcd565b6000611512836001600160a01b03841661450a565b336001600160a01b03821603613f34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610b44565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a7640000613fd0837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615537565b6115129190615561565b6000611512836001600160a01b038416614516565b6000612c6c846001600160a01b03851684614522565b6000614024856140158486615537565b61401f908761554e565b6144f4565b95945050505050565b6000614082826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166145389092919063ffffffff16565b80519091501561304557808060200190518101906140a09190615632565b613045576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610b44565b6000611512838361450a565b60006115128383614547565b6000611512836001600160a01b0384166145d1565b6000612c6c846001600160a01b038516846145ee565b825474010000000000000000000000000000000000000000900460ff161580614196575081155b156141a057505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906141e690700100000000000000000000000000000000900463ffffffff1642615c80565b905080156142a65781831115614228576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546142629083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16614005565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b84821015614343576001600160a01b0384166142f8576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610b44565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610b44565b8483101561443c5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906143879082615c80565b614391878a615c80565b61439b919061554e565b6143a59190615561565b90506001600160a01b0386166143f1576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610b44565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610b44565b6144468584615c80565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60006111408261460b565b600080806144d78585614615565b600081815260029690960160205260409095205494959350505050565b60008183106145035781611512565b5090919050565b60006115128383614621565b600061151283836145d1565b6000612c6c84846001600160a01b0385166145ee565b6060612c6c8484600085614639565b60008181526002830160205260408120548015158061456b575061456b848461450a565b611512576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b657900006044820152606401610b44565b60008181526002830160205260408120819055611512838361473a565b60008281526002840160205260408120829055612c6c8484614746565b6000611140825490565b60006115128383614752565b60008181526001830160205260408120541515611512565b6060824710156146cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610b44565b600080866001600160a01b031685876040516146e79190615e57565b60006040518083038185875af1925050503d8060008114614724576040519150601f19603f3d011682016040523d82523d6000602084013e614729565b606091505b5091509150612c678783838761477c565b6000611512838361480f565b60006115128383614909565b6000826000018281548110614769576147696156c5565b9060005260206000200154905092915050565b606083156148055782516000036147fe576001600160a01b0385163b6147fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610b44565b5081612c6c565b612c6c8383614958565b600081815260018301602052604081205480156148f8576000614833600183615c80565b855490915060009061484790600190615c80565b90508181146148ac576000866000018281548110614867576148676156c5565b906000526020600020015490508087600001848154811061488a5761488a6156c5565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806148bd576148bd615e73565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611140565b6000915050611140565b5092915050565b600081815260018301602052604081205461495057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611140565b506000611140565b8151156149685781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b449190614ac8565b60e0810161114082846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b6001600160a01b03811681146109d557600080fd5b8035614a3881614a18565b919050565b600060208284031215614a4f57600080fd5b813561151281614a18565b60005b83811015614a75578181015183820152602001614a5d565b50506000910152565b60008151808452614a96816020860160208601614a5a565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006115126020830184614a7e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614b2d57614b2d614adb565b60405290565b6040805190810167ffffffffffffffff81118282101715614b2d57614b2d614adb565b6040516080810167ffffffffffffffff81118282101715614b2d57614b2d614adb565b604051610140810167ffffffffffffffff81118282101715614b2d57614b2d614adb565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614be457614be4614adb565b604052919050565b600067ffffffffffffffff821115614c0657614c06614adb565b5060051b60200190565b63ffffffff811681146109d557600080fd5b8035614a3881614c10565b67ffffffffffffffff811681146109d557600080fd5b8035614a3881614c2d565b80151581146109d557600080fd5b8035614a3881614c4e565b60006020808385031215614c7a57600080fd5b823567ffffffffffffffff811115614c9157600080fd5b8301601f81018513614ca257600080fd5b8035614cb5614cb082614bec565b614b9d565b81815260e09182028301840191848201919088841115614cd457600080fd5b938501935b83851015614d7f5780858a031215614cf15760008081fd5b614cf9614b0a565b8535614d0481614a18565b815285870135614d1381614c10565b81880152604086810135614d2681614c10565b90820152606086810135614d3981614c10565b908201526080614d4a878201614c43565b9082015260a0614d5b878201614c43565b9082015260c0614d6c878201614c5c565b9082015283529384019391850191614cd9565b50979650505050505050565b600060a082840312156121de57600080fd5b600060208284031215614daf57600080fd5b813567ffffffffffffffff811115614dc657600080fd5b612c6c84828501614d8b565b600082601f830112614de357600080fd5b81356020614df3614cb083614bec565b82815260069290921b84018101918181019086841115614e1257600080fd5b8286015b84811015614e635760408189031215614e2f5760008081fd5b614e37614b33565b8135614e4281614a18565b815281850135614e5181614a18565b81860152835291830191604001614e16565b509695505050505050565b60008060408385031215614e8157600080fd5b823567ffffffffffffffff80821115614e9957600080fd5b614ea586838701614dd2565b93506020850135915080821115614ebb57600080fd5b50614ec885828601614dd2565b9150509250929050565b60008060408385031215614ee557600080fd5b8235614ef081614a18565b91506020830135614f0081614a18565b809150509250929050565b80516001600160a01b031682526020810151614f2d602084018261ffff169052565b506040810151614f45604084018263ffffffff169052565b506060810151614f5b606084018261ffff169052565b506080810151614f73608084018263ffffffff169052565b5060a0810151614f8960a084018261ffff169052565b5060c0810151614f9f60c084018261ffff169052565b5060e0810151614fba60e08401826001600160a01b03169052565b506101008181015163ffffffff81168483015250506101208181015163ffffffff8116848301526128e3565b61014081016111408284614f0b565b803561ffff81168114614a3857600080fd5b6000602080838503121561501a57600080fd5b823567ffffffffffffffff81111561503157600080fd5b8301601f8101851361504257600080fd5b8035615050614cb082614bec565b81815260079190911b8201830190838101908783111561506f57600080fd5b928401925b828410156150e9576080848903121561508d5760008081fd5b615095614b56565b84356150a081614a18565b81526150ad858701614ff5565b868201526040808601356150c081614c10565b908201526060858101356150d381614c10565b9082015282526080939093019290840190615074565b979650505050505050565b6000806020838503121561510757600080fd5b823567ffffffffffffffff8082111561511f57600080fd5b818501915085601f83011261513357600080fd5b81358181111561514257600080fd5b8660208260061b850101111561515757600080fd5b60209290920196919550909350505050565b60008060006060848603121561517e57600080fd5b833567ffffffffffffffff81111561519557600080fd5b6151a186828701614d8b565b9350506020840135915060408401356151b981614a18565b809150509250925092565b600081518084526020808501945080840160005b8381101561520c57815180516001600160a01b0316885283015161ffff1683880152604090960195908201906001016151d8565b509495945050505050565b60408152600061522a60408301856151c4565b90508260208301529392505050565b80356fffffffffffffffffffffffffffffffff81168114614a3857600080fd5b60006060828403121561526b57600080fd5b6040516060810181811067ffffffffffffffff8211171561528e5761528e614adb565b604052823561529c81614c4e565b81526152aa60208401615239565b60208201526152bb60408401615239565b60408201529392505050565b6020808252825182820181905260009190848201906040850190845b818110156153085783516001600160a01b0316835292840192918401916001016152e3565b50909695505050505050565b6000610140828403121561532757600080fd5b61532f614b79565b61533883614a2d565b815261534660208401614ff5565b602082015261535760408401614c22565b604082015261536860608401614ff5565b606082015261537960808401614c22565b608082015261538a60a08401614ff5565b60a082015261539b60c08401614ff5565b60c08201526153ac60e08401614a2d565b60e08201526101006153bf818501614c22565b908201526101206153d1848201614c22565b908201529392505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261541157600080fd5b83018035915067ffffffffffffffff82111561542c57600080fd5b60200191503681900382131561395c57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261547657600080fd5b83018035915067ffffffffffffffff82111561549157600080fd5b6020019150600681901b360382131561395c57600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614a3857600080fd5b600080604083850312156154e857600080fd5b6154f1836154a9565b91506154ff602084016154a9565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761114057611140615508565b8082018082111561114057611140615508565b600082615597577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b67ffffffffffffffff81811683821601908082111561490257614902615508565b6000602082840312156155cf57600080fd5b5051919050565b6000604082840312156155e857600080fd5b6155f0614b33565b82356155fb81614a18565b815261560960208401614ff5565b60208201529392505050565b60006020828403121561562757600080fd5b815161151281614c2d565b60006020828403121561564457600080fd5b815161151281614c4e565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000612c6c60208301848661564f565b6000602082840312156156be57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361572557615725615508565b5060010190565b60006040828403121561573e57600080fd5b615746614b33565b823561575181614a18565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff81811683821601908082111561490257614902615508565b600067ffffffffffffffff8083168181036157a8576157a8615508565b6001019392505050565b6001600160a01b038716815260a0602082015260006157d560a08301878961564f565b85604084015267ffffffffffffffff8516606084015282810360808401526157fd8185614a7e565b9998505050505050505050565b60006020828403121561581c57600080fd5b815167ffffffffffffffff8082111561583457600080fd5b818401915084601f83011261584857600080fd5b81518181111561585a5761585a614adb565b61588b60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614b9d565b91508082528560208285010111156158a257600080fd5b6158b3816020840160208601614a5a565b50949350505050565b600081518084526020808501945080840160005b8381101561520c57815180516001600160a01b0316885283015183880152604090960195908201906001016158d0565b600081518084526020808501808196508360051b8101915082860160005b85811015615948578284038952615936848351614a7e565b9885019893509084019060010161591e565b5091979650505050505050565b6020815261597060208201835167ffffffffffffffff169052565b6000602083015161598c60408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a08301516159d560c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e0830151610100615a08818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615a366101c0860184614a7e565b92508086015190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0610160818786030181880152615a7585846158bc565b945080880151925050610180818786030181880152615a948584615900565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff82811682821603908082111561490257614902615508565b602080825282518282018190526000919060409081850190868401855b8281101561594857815180516001600160a01b031685528681015163ffffffff90811688870152868201518116878701526060808301519091169086015260808082015167ffffffffffffffff169086015260a080820151615b578288018267ffffffffffffffff169052565b505060c09081015115159085015260e09093019290850190600101615aea565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615bb75780818660040360031b1b83161692505b505092915050565b60008085851115615bcf57600080fd5b83861115615bdc57600080fd5b5050820193919092039150565b600060208284031215615bfb57600080fd5b6040516020810181811067ffffffffffffffff82111715615c1e57615c1e614adb565b6040529135825250919050565b600060208284031215615c3d57600080fd5b611512826154a9565b63ffffffff81811683821601908082111561490257614902615508565b600060208284031215615c7557600080fd5b815161151281614a18565b8181038181111561114057611140615508565b818103600083128015838313168383128216171561490257614902615508565b602080825282518282018190526000919060409081850190868401855b8281101561594857815180516001600160a01b031685528681015161ffff16878601528581015163ffffffff90811687870152606091820151169085015260809093019290850190600101615cd0565b600081615d2f57615d2f615508565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff83168152604060208201526000612c6c60408301846151c4565b600060408284031215615d8657600080fd5b615d8e614b33565b615d97836154a9565b8152602083015161560981614c10565b60208152600061151260208301846158bc565b6020815260006115126020830184615900565b6102208101615e4a82856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b61151260e0830184614f0b565b60008251615e69818460208701614a5a565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"tokensAndPools\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"CannotSendZeroTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedAddress\",\"type\":\"bytes\"}],\"name\":\"InvalidAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"}],\"name\":\"InvalidNopAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTokenPoolConfig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidWithdrawParams\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkBalanceNotSettled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxFeeBalanceReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MessageGasLimitTooHigh\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"maxSize\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"actualSize\",\"type\":\"uint256\"}],\"name\":\"MessageTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MustBeCalledByRouter\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoFeesToPay\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoNopsToPay\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"NotAFeeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByAdminOrOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByOwnerOrAdminOrNop\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PoolAlreadyAdded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PoolDoesNotExist\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"PriceNotFoundForToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"RouterMustSetOriginalSender\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TokenPoolMismatch\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyNops\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedNumberOfTokens\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"UnsupportedToken\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AdminSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"sequenceNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"gasLimit\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"strict\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes[]\",\"name\":\"sourceTokenData\",\"type\":\"bytes[]\"},{\"internalType\":\"bytes32\",\"name\":\"messageId\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"structInternal.EVM2EVMMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"CCIPSendRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"staticConfig\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeConfig\",\"type\":\"tuple[]\"}],\"name\":\"FeeConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NopPaid\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nopWeightsTotal\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"NopsSet\",\"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\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"transferFeeConfig\",\"type\":\"tuple[]\"}],\"name\":\"TokenTransferFeeConfigSet\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"removes\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"internalType\":\"structInternal.PoolUpdate[]\",\"name\":\"adds\",\"type\":\"tuple[]\"}],\"name\":\"applyPoolUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"feeTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"}],\"name\":\"forwardFromRouter\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDynamicConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getExpectedNextSequenceNumber\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"receiver\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"structClient.EVMTokenAmount[]\",\"name\":\"tokenAmounts\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structClient.EVM2AnyMessage\",\"name\":\"message\",\"type\":\"tuple\"}],\"name\":\"getFee\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getFeeTokenConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfig\",\"name\":\"feeTokenConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNopFeesJuels\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getNops\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"weightsTotal\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"sourceToken\",\"type\":\"address\"}],\"name\":\"getPoolBySourceToken\",\"outputs\":[{\"internalType\":\"contractIPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getSenderNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStaticConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"linkToken\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"defaultTxGasLimit\",\"type\":\"uint64\"},{\"internalType\":\"uint96\",\"name\":\"maxNopFeesJuels\",\"type\":\"uint96\"},{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"internalType\":\"structEVM2EVMOnRamp.StaticConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSupportedTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getTokenLimitAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenTransferFeeConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"minFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfig\",\"name\":\"tokenTransferFeeConfig\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"linkAvailableForPayment\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"payNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"setAdmin\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"router\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"maxTokensLength\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerPayloadByte\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destDataAvailabilityOverheadGas\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"destGasPerDataAvailabilityByte\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"destDataAvailabilityMultiplier\",\"type\":\"uint16\"},{\"internalType\":\"address\",\"name\":\"priceRegistry\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"maxDataSize\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.DynamicConfig\",\"name\":\"dynamicConfig\",\"type\":\"tuple\"}],\"name\":\"setDynamicConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"gasMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"premiumMultiplier\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structEVM2EVMOnRamp.FeeTokenConfigArgs[]\",\"name\":\"feeTokenConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setFeeTokenConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"nop\",\"type\":\"address\"},{\"internalType\":\"uint16\",\"name\":\"weight\",\"type\":\"uint16\"}],\"internalType\":\"structEVM2EVMOnRamp.NopAndWeight[]\",\"name\":\"nopsAndWeights\",\"type\":\"tuple[]\"}],\"name\":\"setNops\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"minFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"maxFeeUSD\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"ratio\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"destGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"destBytesOverhead\",\"type\":\"uint32\"}],\"internalType\":\"structEVM2EVMOnRamp.TokenTransferFeeConfigArgs[]\",\"name\":\"tokenTransferFeeConfigArgs\",\"type\":\"tuple[]\"}],\"name\":\"setTokenTransferFeeConfig\",\"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\":[{\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdrawNonLinkFees\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6101806040523480156200001257600080fd5b50604051620083a9380380620083a9833981016040819052620000359162001e40565b8333806000816200008d5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c057620000c08162000323565b50506040805160a081018252602084810180516001600160801b039081168085524263ffffffff169385018490528751151585870181905292518216606086018190529790950151166080909301839052600380546001600160a01b031916909417600160801b9283021760ff60a01b1916600160a01b90910217909255029091176004555086516001600160a01b0316158062000169575060208701516001600160401b0316155b8062000180575060408701516001600160401b0316155b8062000197575060608701516001600160401b0316155b80620001ae575060c08701516001600160a01b0316155b15620001cd576040516306b7c75960e31b815260040160405180910390fd5b6020808801516040808a015181517f8acd72527118c8324937b1a42e02cd246697c3b633f1742f3cae11de233722b3948101949094526001600160401b039283169184019190915216606082015230608082015260a00160408051601f198184030181529181528151602092830120608090815289516001600160a01b0390811660e052928a01516001600160401b0390811661010052918a015182166101205260608a015190911660a0908152908901516001600160601b031660c0908152908901518216610140528801511661016052620002aa86620003ce565b620002b58362000645565b620002c0826200077f565b620002cb81620008e5565b6040805160008082526020820190925262000316916200030e565b6040805180820190915260008082526020820152815260200190600190039081620002e65790505b508662000b0f565b505050505050506200241a565b336001600160a01b038216036200037d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000084565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60e08101516001600160a01b0316620003fa576040516306b7c75960e31b815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055509050507f2a57f7c2027cf032c78b77d4d8d2fbd20ad22e5d5e5b5fb23ac7d7820d44adc66040518060e0016040528060e0516001600160a01b03168152602001610100516001600160401b03168152602001610120516001600160401b0316815260200160a0516001600160401b0316815260200160c0516001600160601b03168152602001610140516001600160a01b03168152602001610160516001600160a01b0316815250826040516200063a92919062002015565b60405180910390a150565b60005b81518110156200074d57600082828151811062000669576200066962002095565b60209081029190910181015160408051608080820183528385015163ffffffff9081168352838501516001600160401b03908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600d90985294909620925183549451925195511515600160a01b0260ff60a01b199688166c010000000000000000000000000296909616600160601b600160a81b031993909716640100000000026001600160601b0319909516911617929092179190911692909217179055506200074581620020c1565b905062000648565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e816040516200063a9190620020dd565b60005b8151811015620008b3576000828281518110620007a357620007a362002095565b6020908102919091018101516040805160a080820183528385015163ffffffff908116835283850151811683870190815260608087015161ffff9081168688019081526080808a0151861693880193845295890151851695870195865297516001600160a01b03166000908152600e909952959097209351845491519651975193518316600160701b0263ffffffff60701b199484166a01000000000000000000000263ffffffff60501b199990971668010000000000000000029890981665ffffffffffff60401b19978416640100000000026001600160401b03199093169190931617179490941693909317919091179190911691909117905550620008ab81620020c1565b905062000782565b507f555c74101f7a15746d31c6731170310e667bcc607996b2fc0b981a7b26a416e9816040516200063a91906200216c565b805160408111156200090a57604051635ad0867d60e11b815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff161580159062000954575060105463ffffffff6c010000000000000000000000008204166001600160601b0390911610155b1562000964576200096462000e12565b600062000972600762001012565b90505b8015620009be576000620009986200098f600184620021f3565b60079062001025565b509050620009a860078262001043565b505080620009b69062002209565b905062000975565b506000805b8281101562000aa6576000848281518110620009e357620009e362002095565b6020026020010151600001519050600085838151811062000a085762000a0862002095565b602002602001015160200151905060e0516001600160a01b0316826001600160a01b0316148062000a4057506001600160a01b038216155b1562000a6b57604051634de938d160e01b81526001600160a01b038316600482015260240162000084565b62000a7d60078361ffff841662001061565b5062000a8e61ffff82168562002223565b935050508062000a9e90620020c1565b9050620009c3565b506010805463ffffffff60601b19166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd249062000b02908390869062002243565b60405180910390a1505050565b60005b825181101562000c4b57600083828151811062000b335762000b3362002095565b6020026020010151600001519050600084838151811062000b585762000b5862002095565b6020908102919091018101510151905062000b75600a8362001081565b62000b9f576040516373913ebd60e01b81526001600160a01b038316600482015260240162000084565b6001600160a01b03811662000bb6600a8462001098565b6001600160a01b03161462000bde57604051630d98f73360e31b815260040160405180910390fd5b62000beb600a83620010af565b1562000c3557604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b50508062000c4390620020c1565b905062000b12565b5060005b815181101562000e0d57600082828151811062000c705762000c7062002095565b6020026020010151600001519050600083838151811062000c955762000c9562002095565b602002602001015160200151905060006001600160a01b0316826001600160a01b0316148062000ccc57506001600160a01b038116155b1562000cea5760405162d8548360e71b815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000d29573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000d4f9190620022b0565b6001600160a01b0316826001600160a01b03161462000d8157604051630d98f73360e31b815260040160405180910390fd5b62000d8f600a8383620010c6565b1562000dde57604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a162000df7565b604051633caf458560e01b815260040160405180910390fd5b50508062000e0590620020c1565b905062000c4f565b505050565b6000546001600160a01b0316331480159062000e3957506002546001600160a01b03163314155b801562000e50575062000e4e600733620010de565b155b1562000e6f5760405163032bb72b60e31b815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff16600081900362000eab5760405163990e30bf60e01b815260040160405180910390fd5b6010546001600160601b03168181101562000ed9576040516311a1ee3b60e31b815260040160405180910390fd5b600062000ee5620010f5565b121562000f0557604051631e9acf1760e31b815260040160405180910390fd5b80600062000f14600762001012565b905060005b8181101562000fec5760008062000f3260078462001025565b909250905060008762000f4f836001600160601b038a16620022d0565b62000f5b9190620022ea565b905062000f6981876200230d565b60e05190965062000f8e906001600160a01b0316846001600160601b03841662001183565b6040516001600160601b03821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a25050508062000fe490620020c1565b905062000f19565b5050601080546001600160601b0319166001600160601b03929092169190911790555050565b60006200101f82620011db565b92915050565b6000808080620010368686620011e8565b9097909650945050505050565b60006200105a836001600160a01b03841662001215565b9392505050565b600062001079846001600160a01b0385168462001234565b949350505050565b60006200105a836001600160a01b03841662001253565b60006200105a836001600160a01b03841662001261565b60006200105a836001600160a01b0384166200126f565b600062001079846001600160a01b038516846200127d565b60006200105a836001600160a01b03841662001295565b60105460e0516040516370a0823160e01b81523060048201526000926001600160601b0316916001600160a01b0316906370a0823190602401602060405180830381865afa1580156200114c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001172919062002330565b6200117e91906200234a565b905090565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663a9059cbb60e01b1790915262000e0d918591620012a316565b60006200101f8262001374565b60008080620011f885856200137f565b600081815260029690960160205260409095205494959350505050565b600081815260028301602052604081208190556200105a83836200138d565b600082815260028401602052604081208290556200107984846200139b565b60006200105a838362001295565b60006200105a8383620013a9565b60006200105a838362001215565b60006200107984846001600160a01b03851662001234565b60006200105a83836200141e565b6040805180820190915260208082527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656490820152600090620012f2906001600160a01b03851690849062001437565b80519091501562000e0d57808060200190518101906200131391906200236d565b62000e0d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840162000084565b60006200101f825490565b60006200105a838362001448565b60006200105a838362001475565b60006200105a838362001580565b600081815260028301602052604081205480151580620013d05750620013d0848462001295565b6200105a5760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b65790000604482015260640162000084565b600081815260018301602052604081205415156200105a565b6060620010798484600085620015d2565b600082600001828154811062001462576200146262002095565b9060005260206000200154905092915050565b600081815260018301602052604081205480156200156e5760006200149c600183620021f3565b8554909150600090620014b290600190620021f3565b90508181146200151e576000866000018281548110620014d657620014d662002095565b9060005260206000200154905080876000018481548110620014fc57620014fc62002095565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200153257620015326200238b565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200101f565b60009150506200101f565b5092915050565b6000818152600183016020526040812054620015c9575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200101f565b5060006200101f565b606082471015620016355760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840162000084565b600080866001600160a01b03168587604051620016539190620023c7565b60006040518083038185875af1925050503d806000811462001692576040519150601f19603f3d011682016040523d82523d6000602084013e62001697565b606091505b509092509050620016ab87838387620016b6565b979650505050505050565b606083156200172a57825160000362001722576001600160a01b0385163b620017225760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162000084565b508162001079565b620010798383815115620017415781518083602001fd5b8060405162461bcd60e51b8152600401620000849190620023e5565b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b03811182821017156200179857620017986200175d565b60405290565b60405161014081016001600160401b03811182821017156200179857620017986200175d565b604080519081016001600160401b03811182821017156200179857620017986200175d565b60405160a081016001600160401b03811182821017156200179857620017986200175d565b60405160c081016001600160401b03811182821017156200179857620017986200175d565b604051601f8201601f191681016001600160401b03811182821017156200185e576200185e6200175d565b604052919050565b6001600160a01b03811681146200187c57600080fd5b50565b80516200188c8162001866565b919050565b80516001600160401b03811681146200188c57600080fd5b600060e08284031215620018bc57600080fd5b620018c662001773565b90508151620018d58162001866565b8152620018e56020830162001891565b6020820152620018f86040830162001891565b60408201526200190b6060830162001891565b606082015260808201516001600160601b03811681146200192b57600080fd5b60808201526200193e60a083016200187f565b60a08201526200195160c083016200187f565b60c082015292915050565b805161ffff811681146200188c57600080fd5b805163ffffffff811681146200188c57600080fd5b600061014082840312156200199857600080fd5b620019a26200179e565b9050620019af826200187f565b8152620019bf602083016200195c565b6020820152620019d2604083016200196f565b6040820152620019e5606083016200195c565b6060820152620019f8608083016200196f565b608082015262001a0b60a083016200195c565b60a082015262001a1e60c083016200195c565b60c082015262001a3160e083016200187f565b60e082015261010062001a468184016200196f565b9082015261012062001a5a8382016200196f565b9082015292915050565b60006001600160401b0382111562001a805762001a806200175d565b5060051b60200190565b600082601f83011262001a9c57600080fd5b8151602062001ab562001aaf8362001a64565b62001833565b82815260069290921b8401810191818101908684111562001ad557600080fd5b8286015b8481101562001b2f576040818903121562001af45760008081fd5b62001afe620017c4565b815162001b0b8162001866565b81528185015162001b1c8162001866565b8186015283529183019160400162001ad9565b509695505050505050565b805180151581146200188c57600080fd5b80516001600160801b03811681146200188c57600080fd5b60006060828403121562001b7657600080fd5b604051606081016001600160401b038111828210171562001b9b5762001b9b6200175d565b60405290508062001bac8362001b3a565b815262001bbc6020840162001b4b565b602082015262001bcf6040840162001b4b565b60408201525092915050565b600082601f83011262001bed57600080fd5b8151602062001c0062001aaf8362001a64565b82815260a0928302850182019282820191908785111562001c2057600080fd5b8387015b8581101562001caf5781818a03121562001c3e5760008081fd5b62001c48620017e9565b815162001c558162001866565b815262001c648287016200196f565b86820152604062001c7781840162001891565b90820152606062001c8a83820162001891565b90820152608062001c9d83820162001b3a565b90820152845292840192810162001c24565b5090979650505050505050565b600082601f83011262001cce57600080fd5b8151602062001ce162001aaf8362001a64565b82815260c0928302850182019282820191908785111562001d0157600080fd5b8387015b8581101562001caf5781818a03121562001d1f5760008081fd5b62001d296200180e565b815162001d368162001866565b815262001d458287016200196f565b86820152604062001d588184016200196f565b90820152606062001d6b8382016200195c565b90820152608062001d7e8382016200196f565b9082015260a062001d918382016200196f565b90820152845292840192810162001d05565b600082601f83011262001db557600080fd5b8151602062001dc862001aaf8362001a64565b82815260069290921b8401810191818101908684111562001de857600080fd5b8286015b8481101562001b2f576040818903121562001e075760008081fd5b62001e11620017c4565b815162001e1e8162001866565b815262001e2d8286016200195c565b8186015283529183019160400162001dec565b6000806000806000806000610300888a03121562001e5d57600080fd5b62001e698989620018a9565b965062001e7a8960e08a0162001984565b6102208901519096506001600160401b038082111562001e9957600080fd5b62001ea78b838c0162001a8a565b965062001eb98b6102408c0162001b63565b95506102a08a015191508082111562001ed157600080fd5b62001edf8b838c0162001bdb565b94506102c08a015191508082111562001ef757600080fd5b62001f058b838c0162001cbc565b93506102e08a015191508082111562001f1d57600080fd5b5062001f2c8a828b0162001da3565b91505092959891949750929550565b80516001600160a01b03168252602081015162001f5e602084018261ffff169052565b50604081015162001f77604084018263ffffffff169052565b50606081015162001f8e606084018261ffff169052565b50608081015162001fa7608084018263ffffffff169052565b5060a081015162001fbe60a084018261ffff169052565b5060c081015162001fd560c084018261ffff169052565b5060e081015162001ff160e08401826001600160a01b03169052565b506101008181015163ffffffff908116918401919091526101209182015116910152565b82516001600160a01b0390811682526020808501516001600160401b0390811691840191909152604080860151821690840152606080860151909116908301526080808501516001600160601b03169083015260a08085015182169083015260c0808501519091169082015261022081016200105a60e083018462001f3b565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620020d657620020d6620020ab565b5060010190565b602080825282518282018190526000919060409081850190868401855b828110156200215f57815180516001600160a01b031685528681015163ffffffff1687860152858101516001600160401b03908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101620020fa565b5091979650505050505050565b602080825282518282018190526000919060409081850190868401855b828110156200215f57815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a091820151169085015260c0909301929085019060010162002189565b818103818111156200101f576200101f620020ab565b6000816200221b576200221b620020ab565b506000190190565b63ffffffff818116838216019080821115620015795762001579620020ab565b6000604080830163ffffffff8616845260208281860152818651808452606087019150828801935060005b81811015620022a257845180516001600160a01b0316845284015161ffff168484015293830193918501916001016200226e565b509098975050505050505050565b600060208284031215620022c357600080fd5b81516200105a8162001866565b80820281158282048414176200101f576200101f620020ab565b6000826200230857634e487b7160e01b600052601260045260246000fd5b500490565b6001600160601b03828116828216039080821115620015795762001579620020ab565b6000602082840312156200234357600080fd5b5051919050565b8181036000831280158383131683831282161715620015795762001579620020ab565b6000602082840312156200238057600080fd5b6200105a8262001b3a565b634e487b7160e01b600052603160045260246000fd5b60005b83811015620023be578181015183820152602001620023a4565b50506000910152565b60008251620023db818460208701620023a1565b9190910192915050565b602081526000825180602084015262002406816040850160208701620023a1565b601f01601f19169190910160400192915050565b60805160a05160c05160e05161010051610120516101405161016051615e8862002521600039600081816103340152818161147a0152613cf10152600081816103050152818161139c01528181611404015281816119e301528181611a4b0152613cc201526000818161027101528181610b1c01528181611de00152613c2e01526000818161024101528181611b160152613bfe01526000818161021201528181610eeb0152818161178e0152818161188f0152818161231101528181612f24015281816131840152613bcf0152600081816102d10152818161195b0152613c8e0152600081816102a10152818161248f0152613c5e01526000611ea80152615e886000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c806379ba5097116100f9578063c92b283211610097578063e687b40a11610071578063e687b40a1461092b578063eff7cc481461093e578063f25561fd14610946578063f2fde38b1461095957600080fd5b8063c92b2832146108fb578063d09dc3391461090e578063d3c7c2c71461091657600080fd5b80638da5cb5b116100d35780638da5cb5b146107bc5780639a113c36146107cd578063a7d3e02f146108d2578063b06d41bc146108e557600080fd5b806379ba50971461078e5780637ec7575114610796578063856c8247146107a957600080fd5b8063549e946f116101665780635d86f141116101405780635d86f141146105e6578063704b6c02146105f95780637437ff9f1461060c57806376f6ae761461077b57600080fd5b8063549e946f1461058e57806354b71468146105a1578063599f6431146105c157600080fd5b806338724a95116101a257806338724a95146104d35780633a87ac53146104f45780634120fccd14610509578063546719cd1461052a57600080fd5b806306285c69146101c95780631772047e1461037a578063181f5a771461048a575b600080fd5b6103646040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101919091526040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316815250905090565b60405161037191906149a5565b60405180910390f35b61043c610388366004614a46565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152506001600160a01b03166000908152600e6020908152604091829020825160a081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e01000000000000000000000000000090920416608082015290565b6040516103719190815163ffffffff908116825260208084015182169083015260408084015161ffff1690830152606080840151821690830152608092830151169181019190915260a00190565b6104c66040518060400160405280601381526020017f45564d3245564d4f6e52616d7020312e322e300000000000000000000000000081525081565b6040516103719190614ad1565b6104e66104e1366004614af6565b61096c565b604051908152602001610371565b610507610502366004614d01565b610d92565b005b610511610da8565b60405167ffffffffffffffff9091168152602001610371565b610532610ddc565b604051610371919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b61050761059c366004614d65565b610e8c565b6010546040516bffffffffffffffffffffffff9091168152602001610371565b6002546001600160a01b03165b6040516001600160a01b039091168152602001610371565b6105ce6105f4366004614a46565b611041565b610507610607366004614a46565b6110a0565b61076e6040805161014081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101919091525060408051610140810182526005546001600160a01b03808216835261ffff7401000000000000000000000000000000000000000083048116602085015263ffffffff76010000000000000000000000000000000000000000000084048116958501959095527a0100000000000000000000000000000000000000000000000000008304811660608501527c0100000000000000000000000000000000000000000000000000000000928390048516608085015260065480821660a086015262010000810490911660c0850152640100000000810490911660e08401527801000000000000000000000000000000000000000000000000810484166101008401520490911661012082015290565b6040516103719190614e79565b610507610789366004614e88565b61116a565b610507611222565b6105076107a4366004614f2c565b611305565b6105116107b7366004614a46565b61136e565b6000546001600160a01b03166105ce565b6108886107db366004614a46565b604080516080810182526000808252602082018190529181018290526060810191909152506001600160a01b03166000908152600d60209081526040918290208251608081018452905463ffffffff8116825267ffffffffffffffff64010000000082048116938301939093526c0100000000000000000000000081049092169281019290925260ff74010000000000000000000000000000000000000000909104161515606082015290565b60408051825163ffffffff16815260208084015167ffffffffffffffff90811691830191909152838301511691810191909152606091820151151591810191909152608001610371565b6104e66108e036600461503c565b611476565b6108ed611f1a565b6040516103719291906150ea565b61050761090936600461513a565b61201e565b6104e6612086565b61091e612090565b60405161037191906151a8565b6105076109393660046151f5565b612141565b610507612152565b6105076109543660046152d3565b6123e9565b610507610967366004614a46565b61244f565b60008061098461097f60808501856153c6565b612460565b90506109af61099660208501856153c6565b83519091506109a8604087018761542b565b9050612554565b6000600d816109c46080870160608801614a46565b6001600160a01b0316815260208082019290925260409081016000208151608081018352905463ffffffff81168252640100000000810467ffffffffffffffff908116948301949094526c010000000000000000000000008104909316918101919091527401000000000000000000000000000000000000000090910460ff16151560608201819052909150610aa757610a646080850160608601614a46565b6040517fa7499d200000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024015b60405180910390fd5b600654600090819064010000000090046001600160a01b031663ffdb4b37610ad56080890160608a01614a46565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b03909116600482015267ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044016040805180830381865afa158015610b60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8491906154bf565b9092509050806000808080610b9c60408c018c61542b565b90501115610bd657610bca610bb760808c0160608d01614a46565b87610bc560408e018e61542b565b61267d565b91945092509050610bf2565b8651610bef9063ffffffff16662386f26fc10000615521565b92505b6040870151610c0b9067ffffffffffffffff1684615521565b60208881015160055492955060009267ffffffffffffffff9091169163ffffffff8616917a010000000000000000000000000000000000000000000000000000900461ffff1690610c5e908f018f6153c6565b610c69929150615521565b6005548c51610c9891760100000000000000000000000000000000000000000000900463ffffffff1690615538565b610ca29190615538565b610cac9190615538565b610cb69190615521565b610cd0906dffffffffffffffffffffffffffff8716615521565b60065490915060009062010000900461ffff1615610d44576000607060ff16887bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16901c9050610d40818e8060200190610d2691906153c6565b90508f8060400190610d38919061542b565b905087612987565b9150505b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff881681610d6e8488615538565b610d789190615538565b610d82919061554b565b9c9b505050505050505050505050565b610d9a612a59565b610da48282612acf565b5050565b601054600090610dd790700100000000000000000000000000000000900467ffffffffffffffff166001615586565b905090565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526040805160a0810182526003546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff1660208501527401000000000000000000000000000000000000000090920460ff161515938301939093526004548084166060840152049091166080820152610dd790612e2f565b6000546001600160a01b03163314801590610eb257506002546001600160a01b03163314155b15610ee9576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161480610f3057506001600160a01b038116155b15610f67576040517f232cb97f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000610f71612ee1565b1215610fa9576040517f02075e0000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152610da49082906001600160a01b038516906370a0823190602401602060405180830381865afa15801561100c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103091906155a7565b6001600160a01b0385169190612fa1565b600061104e600a83613021565b61108f576040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610a9e565b61109a600a83613036565b92915050565b6000546001600160a01b031633148015906110c657506002546001600160a01b03163314155b156110fd576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040519081527f8fe72c3e0020beb3234e76ae6676fa576fbfcae600af1c4fea44784cf0db329c906020015b60405180910390a150565b6000546001600160a01b0316331480159061119057506002546001600160a01b03163314155b156111c7576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610da48282808060200260200160405190810160405280939291908181526020016000905b8282101561121857611209604083028601368190038101906155c0565b815260200190600101906111ec565b505050505061304b565b6001546001600160a01b03163314611296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610a9e565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000546001600160a01b0316331480159061132b57506002546001600160a01b03163314155b15611362576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61136b816132be565b50565b6001600160a01b0381166000908152600f602052604081205467ffffffffffffffff16801580156113c757507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b1561109a576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa15801561144b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061146f91906155ff565b9392505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114fa919061561c565b15611531576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038216611571576040517fa4ec747900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005546001600160a01b031633146115b5576040517f1c0a352900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6115bf84806153c6565b9050602014611606576115d284806153c6565b6040517f370d875f000000000000000000000000000000000000000000000000000000008152600401610a9e929190615682565b600061161285806153c6565b81019061161f9190615696565b90506001600160a01b038111806116365750600a81105b15611645576115d285806153c6565b600061165761097f60808801886153c6565b5190506000611669604088018861542b565b9150611686905061167d60208901896153c6565b90508383612554565b80156117845760005b81811015611707576116a4604089018961542b565b828181106116b4576116b46156af565b905060400201602001356000036116f7576040517f5cf0444900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611700816156de565b905061168f565b50611784611718604089018961542b565b808060200260200160405190810160405280939291908181526020016000905b828210156117645761175560408302860136819003810190615716565b81526020019060010190611738565b505060065464010000000090046001600160a01b03169250613484915050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166117be6080890160608a01614a46565b6001600160a01b03160361182257601080548791906000906117ef9084906bffffffffffffffffffffffff16615750565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611949565b60065464010000000090046001600160a01b03166241e5be61184a60808a0160608b01614a46565b60405160e083901b7fffffffff000000000000000000000000000000000000000000000000000000001681526001600160a01b039182166004820152602481018a90527f00000000000000000000000000000000000000000000000000000000000000009091166044820152606401602060405180830381865afa1580156118d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fa91906155a7565b6010805460009061191a9084906bffffffffffffffffffffffff16615750565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055505b6010546bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116911611156119b6576040517fe5c7a49100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b0385166000908152600f602052604090205467ffffffffffffffff16158015611a0e57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611b06576040517f856c82470000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063856c824790602401602060405180830381865afa158015611a92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ab691906155ff565b6001600160a01b0386166000908152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff929092169190911790555b6000604051806101a001604052807f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff168152602001876001600160a01b03168152602001856001600160a01b0316815260200160108081819054906101000a900467ffffffffffffffff16611b8390615775565b825467ffffffffffffffff9182166101009390930a838102908302199091161790925582526020808301879052600060408085018290526001600160a01b038c168252600f90925290812080546060909401939092611be29116615775565b825467ffffffffffffffff9182166101009390930a83810292021916179091558152602001611c1760808b0160608c01614a46565b6001600160a01b03168152602001888152602001898060200190611c3b91906153c6565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250505090825250602001611c8260408b018b61542b565b808060200260200160405190810160405280939291908181526020016000905b82821015611cce57611cbf60408302860136819003810190615716565b81526020019060010190611ca2565b505050505081526020018367ffffffffffffffff811115611cf157611cf1614b2b565b604051908082528060200260200182016040528015611d2457816020015b6060815260200190600190039081611d0f5790505b508152600060209091018190529091505b82811015611ea1576000611d4c60408b018b61542b565b83818110611d5c57611d5c6156af565b905060400201803603810190611d729190615716565b9050611d818160000151611041565b6001600160a01b0316639687544589611d9a8d806153c6565b60208087015160408051928301815260008352517fffffffff0000000000000000000000000000000000000000000000000000000060e088901b168152611e08959493927f00000000000000000000000000000000000000000000000000000000000000009160040161579c565b6000604051808303816000875af1158015611e27573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611e6d91908101906157f4565b8361016001518381518110611e8457611e846156af565b60200260200101819052505080611e9a906156de565b9050611d35565b50611ecc817f000000000000000000000000000000000000000000000000000000000000000061363f565b6101808201526040517fd0c3c799bf9e2639de44391e7f524d229b2b55f5b1ea94b2bf7da42f7243dddd90611f0290839061593f565b60405180910390a16101800151979650505050505050565b6060600080611f2960076137b8565b90508067ffffffffffffffff811115611f4457611f44614b2b565b604051908082528060200260200182016040528015611f8957816020015b6040805180820190915260008082526020820152815260200190600190039081611f625790505b50925060005b81811015611ffb57600080611fa56007846137c3565b915091506040518060400160405280836001600160a01b031681526020018261ffff16815250868481518110611fdd57611fdd6156af565b6020026020010181905250505080611ff4906156de565b9050611f8f565b505060105491926c0100000000000000000000000090920463ffffffff16919050565b6000546001600160a01b0316331480159061204457506002546001600160a01b03163314155b1561207b576040517ff6cd562000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61136b6003826137e1565b6000610dd7612ee1565b6060600061209e600a6139b9565b67ffffffffffffffff8111156120b6576120b6614b2b565b6040519080825280602002602001820160405280156120df578160200160208202803683370190505b50905060005b815181101561213b576120f9600a826139c4565b5082828151811061210c5761210c6156af565b60200260200101816001600160a01b03166001600160a01b03168152505080612134906156de565b90506120e5565b50919050565b612149612a59565b61136b816139d3565b6000546001600160a01b0316331480159061217857506002546001600160a01b03163314155b801561218c575061218a600733613d2b565b155b156121c3576040517f195db95800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff166000819003612217576040517f990e30bf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546bffffffffffffffffffffffff1681811015612262576040517f8d0f71d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061226c612ee1565b12156122a4576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060006122b160076137b8565b905060005b818110156123a6576000806122cc6007846137c3565b90925090506000876122ec836bffffffffffffffffffffffff8a16615521565b6122f6919061554b565b90506123028187615a92565b95506123466001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016846bffffffffffffffffffffffff8416612fa1565b6040516bffffffffffffffffffffffff821681526001600160a01b038416907f55fdec2aab60a41fa5abb106670eb1006f5aeaee1ba7afea2bc89b5b3ec7678f9060200160405180910390a25050508061239f906156de565b90506122b6565b5050601080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff929092169190911790555050565b6000546001600160a01b0316331480159061240f57506002546001600160a01b03163314155b15612446576040517ffbdb8e5600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61136b81613d40565b612457612a59565b61136b81613ecb565b60408051602081019091526000815260008290036124b65750604080516020810190915267ffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016815261109a565b7f97a657c9000000000000000000000000000000000000000000000000000000006124e18385615ab7565b7fffffffff00000000000000000000000000000000000000000000000000000000161461253a576040517f5247fdce00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6125478260048186615aff565b81019061146f9190615b29565b6006547801000000000000000000000000000000000000000000000000900463ffffffff16808411156125bd576040517f869337890000000000000000000000000000000000000000000000000000000081526004810182905260248101859052604401610a9e565b6006547c0100000000000000000000000000000000000000000000000000000000900463ffffffff1683111561261f576040517f4c4fc93a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055474010000000000000000000000000000000000000000900461ffff16821115612677576040517f4c056b6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505050565b6000808083815b8181101561297b5760008787838181106126a0576126a06156af565b9050604002018036038101906126b69190615716565b80516001600160a01b03166000908152600e6020908152604091829020825160a081018452905463ffffffff8082168352640100000000820481169383019390935261ffff68010000000000000000820416938201939093526a01000000000000000000008304821660608201526e010000000000000000000000000000909204811660808301528251929350909161275391600a919061302116565b6127975781516040517fbf16aab60000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a9e565b604081015160009061ffff16156128bb5760008c6001600160a01b031684600001516001600160a01b03161461285e5760065484516040517f4ab35b0b0000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201526401000000009092041690634ab35b0b90602401602060405180830381865afa158015612833573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128579190615b6b565b9050612861565b508a5b620186a0836040015161ffff166128a38660200151847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16613fa690919063ffffffff16565b6128ad9190615521565b6128b7919061554b565b9150505b60608201516128ca9088615b86565b96508160800151866128dc9190615b86565b82519096506000906128fb9063ffffffff16662386f26fc10000615521565b90508082101561291a5761290f818a615538565b98505050505061296b565b6000836020015163ffffffff16662386f26fc100006129399190615521565b9050808311156129595761294d818b615538565b9950505050505061296b565b612963838b615538565b995050505050505b612974816156de565b9050612684565b50509450945094915050565b60008063ffffffff831661299c608086615521565b6129a887610220615538565b6129b29190615538565b6129bc9190615538565b6005546006549192506000917c010000000000000000000000000000000000000000000000000000000090910463ffffffff16906129fe9061ffff1684615521565b612a089190615538565b60065490915062010000900461ffff16612a326dffffffffffffffffffffffffffff891683615521565b612a3c9190615521565b612a4c90655af3107a4000615521565b925050505b949350505050565b6000546001600160a01b03163314612acd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610a9e565b565b60005b8251811015612c30576000838281518110612aef57612aef6156af565b60200260200101516000015190506000848381518110612b1157612b116156af565b6020026020010151602001519050612b3382600a61302190919063ffffffff16565b612b74576040517f73913ebd0000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610a9e565b6001600160a01b038116612b89600a84613036565b6001600160a01b031614612bc9576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612bd4600a83613fe3565b15612c1d57604080516001600160a01b038085168252831660208201527f987eb3c2f78454541205f72f34839b434c306c9eaf4922efd7c0c3060fdb2e4c910160405180910390a15b505080612c29906156de565b9050612ad2565b5060005b8151811015612e2a576000828281518110612c5157612c516156af565b60200260200101516000015190506000838381518110612c7357612c736156af565b602002602001015160200151905060006001600160a01b0316826001600160a01b03161480612ca957506001600160a01b038116155b15612ce0576040517f6c2a418000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03166321df0da76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d429190615ba3565b6001600160a01b0316826001600160a01b031614612d8c576040517f6cc7b99800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d98600a8383613ff8565b15612de557604080516001600160a01b038085168252831660208201527f95f865c2808f8b2a85eea2611db7843150ee7835ef1403f9755918a97d76933c910160405180910390a1612e17565b6040517f3caf458500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505080612e23906156de565b9050612c34565b505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152612ebd82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642612ea19190615bc0565b85608001516fffffffffffffffffffffffffffffffff1661400e565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b6010546040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000916bffffffffffffffffffffffff16907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612f73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9791906155a7565b610dd79190615bd3565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052612e2a908490614036565b600061146f836001600160a01b038416614135565b600061146f836001600160a01b038416614141565b80516040811115613088576040517fb5a10cfa00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546c01000000000000000000000000900463ffffffff16158015906130d6575060105463ffffffff6c010000000000000000000000008204166bffffffffffffffffffffffff90911610155b156130e3576130e3612152565b60006130ef60076137b8565b90505b8015613131576000613110613108600184615bc0565b6007906137c3565b50905061311e60078261414d565b50508061312a90615bf3565b90506130f2565b506000805b8281101561323f576000848281518110613152576131526156af565b60200260200101516000015190506000858381518110613174576131746156af565b60200260200101516020015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614806131c957506001600160a01b038216155b1561320b576040517f4de938d10000000000000000000000000000000000000000000000000000000081526001600160a01b0383166004820152602401610a9e565b61321b60078361ffff8416614162565b5061322a61ffff821685615b86565b9350505080613238906156de565b9050613136565b50601080547fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff166c0100000000000000000000000063ffffffff8416021790556040517f8c337bff38141c507abd25c547606bdde78fe8c12e941ab613f3a565fea6cd24906132b19083908690615c28565b60405180910390a1505050565b60005b81518110156134545760008282815181106132de576132de6156af565b6020908102919091018101516040805160a080820183528385015163ffffffff908116835283850151811683870190815260608087015161ffff9081168688019081526080808a0151861693880193845295890151851695870195865297516001600160a01b03166000908152600e9099529590972093518454915196519751935183166e010000000000000000000000000000027fffffffffffffffffffffffffffff00000000ffffffffffffffffffffffffffff9484166a0100000000000000000000027fffffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffff999097166801000000000000000002989098167fffffffffffffffffffffffffffffffffffff000000000000ffffffffffffffff978416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909316919093161717949094169390931791909117919091169190911790555061344d816156de565b90506132c1565b507f555c74101f7a15746d31c6731170310e667bcc607996b2fc0b981a7b26a416e98160405161115f9190615c47565b81516000805b82811015613631576000846001600160a01b031663d02641a08784815181106134b5576134b56156af565b6020908102919091010151516040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b0390911660048201526024016040805180830381865afa15801561351c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135409190615ccc565b5190507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81166000036135c55785828151811061357b5761357b6156af565b6020908102919091010151516040517f9a655f7b0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152602401610a9e565b6136138683815181106135da576135da6156af565b602002602001015160200151827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16613fa690919063ffffffff16565b61361d9084615538565b9250508061362a906156de565b905061348a565b506126776003826000614178565b60008060001b8284602001518560400151866060015187608001518860a001518960c001518a60e001518b61010001516040516020016136d59897969594939291906001600160a01b039889168152968816602088015267ffffffffffffffff95861660408801526060870194909452911515608086015290921660a0840152921660c082015260e08101919091526101000190565b604051602081830303815290604052805190602001208561012001518051906020012086610140015160405160200161370e9190615cff565b6040516020818303038152906040528051906020012087610160015160405160200161373a9190615d12565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120908301979097528101949094526060840192909252608083015260a082015260c081019190915260e00160405160208183030381529060405280519060200120905092915050565b600061109a826144c7565b60008080806137d286866144d2565b909450925050505b9250929050565b815460009061380a90700100000000000000000000000000000000900463ffffffff1642615bc0565b905080156138ac5760018301548354613852916fffffffffffffffffffffffffffffffff8082169281169185917001000000000000000000000000000000009091041661400e565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b602082015183546138d2916fffffffffffffffffffffffffffffffff90811691166144fd565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c19906132b19084908151151581526020808301516fffffffffffffffffffffffffffffffff90811691830191909152604092830151169181019190915260600190565b600061109a826137b8565b60008080806137d286866137c3565b60e08101516001600160a01b0316613a17576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600560008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160000160146101000a81548161ffff021916908361ffff16021790555060408201518160000160166101000a81548163ffffffff021916908363ffffffff160217905550606082015181600001601a6101000a81548161ffff021916908361ffff160217905550608082015181600001601c6101000a81548163ffffffff021916908363ffffffff16021790555060a08201518160010160006101000a81548161ffff021916908361ffff16021790555060c08201518160010160026101000a81548161ffff021916908361ffff16021790555060e08201518160010160046101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff16021790555061012082015181600101601c6101000a81548163ffffffff021916908363ffffffff1602179055509050507f2a57f7c2027cf032c78b77d4d8d2fbd20ad22e5d5e5b5fb23ac7d7820d44adc66040518060e001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006bffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152508260405161115f929190615d25565b600061146f836001600160a01b038416614513565b60005b8151811015613e9b576000828281518110613d6057613d606156af565b60209081029190910181015160408051608080820183528385015163ffffffff90811683528385015167ffffffffffffffff908116848801908152606080880151831686880190815294880151151590860190815296516001600160a01b03166000908152600d9098529490962092518354945192519551151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9688166c0100000000000000000000000002969096167fffffffffffffffffffffff000000000000000000ffffffffffffffffffffffff93909716640100000000027fffffffffffffffffffffffffffffffffffffffff00000000000000000000000090951691161792909217919091169290921717905550613e94816156de565b9050613d43565b507f067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e8160405161115f9190615daf565b336001600160a01b03821603613f3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610a9e565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000670de0b6b3a7640000613fd9837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8616615521565b61146f919061554b565b600061146f836001600160a01b03841661451f565b6000612a51846001600160a01b0385168461452b565b600061402d8561401e8486615521565b6140289087615538565b6144fd565b95945050505050565b600061408b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166145419092919063ffffffff16565b805190915015612e2a57808060200190518101906140a9919061561c565b612e2a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a9e565b600061146f8383614513565b600061146f8383614550565b600061146f836001600160a01b0384166145da565b6000612a51846001600160a01b038516846145f7565b825474010000000000000000000000000000000000000000900460ff16158061419f575081155b156141a957505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906141ef90700100000000000000000000000000000000900463ffffffff1642615bc0565b905080156142af5781831115614231576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461426b9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1661400e565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b8482101561434c576001600160a01b038416614301576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610a9e565b6040517f1a76572a00000000000000000000000000000000000000000000000000000000815260048101839052602481018690526001600160a01b0385166044820152606401610a9e565b848310156144455760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906143909082615bc0565b61439a878a615bc0565b6143a49190615538565b6143ae919061554b565b90506001600160a01b0386166143fa576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610a9e565b6040517fd0c8d23a00000000000000000000000000000000000000000000000000000000815260048101829052602481018690526001600160a01b0387166044820152606401610a9e565b61444f8584615bc0565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b600061109a82614614565b600080806144e0858561461e565b600081815260029690960160205260409095205494959350505050565b600081831061450c578161146f565b5090919050565b600061146f838361462a565b600061146f83836145da565b6000612a5184846001600160a01b0385166145f7565b6060612a518484600085614642565b60008181526002830160205260408120548015158061457457506145748484614513565b61146f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b657900006044820152606401610a9e565b6000818152600283016020526040812081905561146f8383614743565b60008281526002840160205260408120829055612a51848461474f565b600061109a825490565b600061146f838361475b565b6000818152600183016020526040812054151561146f565b6060824710156146d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a9e565b600080866001600160a01b031685876040516146f09190615e30565b60006040518083038185875af1925050503d806000811461472d576040519150601f19603f3d011682016040523d82523d6000602084013e614732565b606091505b5091509150612a4c87838387614785565b600061146f8383614818565b600061146f8383614912565b6000826000018281548110614772576147726156af565b9060005260206000200154905092915050565b6060831561480e578251600003614807576001600160a01b0385163b614807576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a9e565b5081612a51565b612a518383614961565b6000818152600183016020526040812054801561490157600061483c600183615bc0565b855490915060009061485090600190615bc0565b90508181146148b5576000866000018281548110614870576148706156af565b9060005260206000200154905080876000018481548110614893576148936156af565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806148c6576148c6615e4c565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061109a565b600091505061109a565b5092915050565b60008181526001830160205260408120546149595750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561109a565b50600061109a565b8151156149715781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9e9190614ad1565b60e0810161109a82846001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b6001600160a01b038116811461136b57600080fd5b8035614a4181614a21565b919050565b600060208284031215614a5857600080fd5b813561146f81614a21565b60005b83811015614a7e578181015183820152602001614a66565b50506000910152565b60008151808452614a9f816020860160208601614a63565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061146f6020830184614a87565b600060a0828403121561213b57600080fd5b600060208284031215614b0857600080fd5b813567ffffffffffffffff811115614b1f57600080fd5b612a5184828501614ae4565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715614b7d57614b7d614b2b565b60405290565b60405160c0810167ffffffffffffffff81118282101715614b7d57614b7d614b2b565b604051610140810167ffffffffffffffff81118282101715614b7d57614b7d614b2b565b60405160a0810167ffffffffffffffff81118282101715614b7d57614b7d614b2b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715614c3457614c34614b2b565b604052919050565b600067ffffffffffffffff821115614c5657614c56614b2b565b5060051b60200190565b600082601f830112614c7157600080fd5b81356020614c86614c8183614c3c565b614bed565b82815260069290921b84018101918181019086841115614ca557600080fd5b8286015b84811015614cf65760408189031215614cc25760008081fd5b614cca614b5a565b8135614cd581614a21565b815281850135614ce481614a21565b81860152835291830191604001614ca9565b509695505050505050565b60008060408385031215614d1457600080fd5b823567ffffffffffffffff80821115614d2c57600080fd5b614d3886838701614c60565b93506020850135915080821115614d4e57600080fd5b50614d5b85828601614c60565b9150509250929050565b60008060408385031215614d7857600080fd5b8235614d8381614a21565b91506020830135614d9381614a21565b809150509250929050565b80516001600160a01b031682526020810151614dc0602084018261ffff169052565b506040810151614dd8604084018263ffffffff169052565b506060810151614dee606084018261ffff169052565b506080810151614e06608084018263ffffffff169052565b5060a0810151614e1c60a084018261ffff169052565b5060c0810151614e3260c084018261ffff169052565b5060e0810151614e4d60e08401826001600160a01b03169052565b506101008181015163ffffffff81168483015250506101208181015163ffffffff811684830152612677565b610140810161109a8284614d9e565b60008060208385031215614e9b57600080fd5b823567ffffffffffffffff80821115614eb357600080fd5b818501915085601f830112614ec757600080fd5b813581811115614ed657600080fd5b8660208260061b8501011115614eeb57600080fd5b60209290920196919550909350505050565b63ffffffff8116811461136b57600080fd5b8035614a4181614efd565b803561ffff81168114614a4157600080fd5b60006020808385031215614f3f57600080fd5b823567ffffffffffffffff811115614f5657600080fd5b8301601f81018513614f6757600080fd5b8035614f75614c8182614c3c565b81815260c09182028301840191848201919088841115614f9457600080fd5b938501935b838510156150305780858a031215614fb15760008081fd5b614fb9614b83565b8535614fc481614a21565b815285870135614fd381614efd565b81880152604086810135614fe681614efd565b908201526060614ff7878201614f1a565b9082015260808681013561500a81614efd565b9082015260a08681013561501d81614efd565b9082015283529384019391850191614f99565b50979650505050505050565b60008060006060848603121561505157600080fd5b833567ffffffffffffffff81111561506857600080fd5b61507486828701614ae4565b93505060208401359150604084013561508c81614a21565b809150509250925092565b600081518084526020808501945080840160005b838110156150df57815180516001600160a01b0316885283015161ffff1683880152604090960195908201906001016150ab565b509495945050505050565b6040815260006150fd6040830185615097565b90508260208301529392505050565b801515811461136b57600080fd5b80356fffffffffffffffffffffffffffffffff81168114614a4157600080fd5b60006060828403121561514c57600080fd5b6040516060810181811067ffffffffffffffff8211171561516f5761516f614b2b565b604052823561517d8161510c565b815261518b6020840161511a565b602082015261519c6040840161511a565b60408201529392505050565b6020808252825182820181905260009190848201906040850190845b818110156151e95783516001600160a01b0316835292840192918401916001016151c4565b50909695505050505050565b6000610140828403121561520857600080fd5b615210614ba6565b61521983614a36565b815261522760208401614f1a565b602082015261523860408401614f0f565b604082015261524960608401614f1a565b606082015261525a60808401614f0f565b608082015261526b60a08401614f1a565b60a082015261527c60c08401614f1a565b60c082015261528d60e08401614a36565b60e08201526101006152a0818501614f0f565b908201526101206152b2848201614f0f565b908201529392505050565b67ffffffffffffffff8116811461136b57600080fd5b600060208083850312156152e657600080fd5b823567ffffffffffffffff8111156152fd57600080fd5b8301601f8101851361530e57600080fd5b803561531c614c8182614c3c565b81815260a0918202830184019184820191908884111561533b57600080fd5b938501935b838510156150305780858a0312156153585760008081fd5b615360614bca565b853561536b81614a21565b81528587013561537a81614efd565b8188015260408681013561538d816152bd565b908201526060868101356153a0816152bd565b908201526080868101356153b38161510c565b9082015283529384019391850191615340565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126153fb57600080fd5b83018035915067ffffffffffffffff82111561541657600080fd5b6020019150368190038213156137da57600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261546057600080fd5b83018035915067ffffffffffffffff82111561547b57600080fd5b6020019150600681901b36038213156137da57600080fd5b80517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff81168114614a4157600080fd5b600080604083850312156154d257600080fd5b6154db83615493565b91506154e960208401615493565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761109a5761109a6154f2565b8082018082111561109a5761109a6154f2565b600082615581577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b67ffffffffffffffff81811683821601908082111561490b5761490b6154f2565b6000602082840312156155b957600080fd5b5051919050565b6000604082840312156155d257600080fd5b6155da614b5a565b82356155e581614a21565b81526155f360208401614f1a565b60208201529392505050565b60006020828403121561561157600080fd5b815161146f816152bd565b60006020828403121561562e57600080fd5b815161146f8161510c565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b602081526000612a51602083018486615639565b6000602082840312156156a857600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361570f5761570f6154f2565b5060010190565b60006040828403121561572857600080fd5b615730614b5a565b823561573b81614a21565b81526020928301359281019290925250919050565b6bffffffffffffffffffffffff81811683821601908082111561490b5761490b6154f2565b600067ffffffffffffffff808316818103615792576157926154f2565b6001019392505050565b6001600160a01b038716815260a0602082015260006157bf60a083018789615639565b85604084015267ffffffffffffffff8516606084015282810360808401526157e78185614a87565b9998505050505050505050565b60006020828403121561580657600080fd5b815167ffffffffffffffff8082111561581e57600080fd5b818401915084601f83011261583257600080fd5b81518181111561584457615844614b2b565b61587560207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614bed565b915080825285602082850101111561588c57600080fd5b61589d816020840160208601614a63565b50949350505050565b600081518084526020808501945080840160005b838110156150df57815180516001600160a01b0316885283015183880152604090960195908201906001016158ba565b600081518084526020808501808196508360051b8101915082860160005b85811015615932578284038952615920848351614a87565b98850198935090840190600101615908565b5091979650505050505050565b6020815261595a60208201835167ffffffffffffffff169052565b6000602083015161597660408401826001600160a01b03169052565b5060408301516001600160a01b038116606084015250606083015167ffffffffffffffff8116608084015250608083015160a083015260a08301516159bf60c084018215159052565b5060c083015167ffffffffffffffff811660e08401525060e08301516101006159f2818501836001600160a01b03169052565b840151610120848101919091528401516101a061014080860182905291925090615a206101c0860184614a87565b92508086015190507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0610160818786030181880152615a5f85846158a6565b945080880151925050610180818786030181880152615a7e85846158ea565b970151959092019490945250929392505050565b6bffffffffffffffffffffffff82811682821603908082111561490b5761490b6154f2565b7fffffffff000000000000000000000000000000000000000000000000000000008135818116916004851015615af75780818660040360031b1b83161692505b505092915050565b60008085851115615b0f57600080fd5b83861115615b1c57600080fd5b5050820193919092039150565b600060208284031215615b3b57600080fd5b6040516020810181811067ffffffffffffffff82111715615b5e57615b5e614b2b565b6040529135825250919050565b600060208284031215615b7d57600080fd5b61146f82615493565b63ffffffff81811683821601908082111561490b5761490b6154f2565b600060208284031215615bb557600080fd5b815161146f81614a21565b8181038181111561109a5761109a6154f2565b818103600083128015838313168383128216171561490b5761490b6154f2565b600081615c0257615c026154f2565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b63ffffffff83168152604060208201526000612a516040830184615097565b602080825282518282018190526000919060409081850190868401855b8281101561593257815180516001600160a01b031685528681015163ffffffff908116888701528682015181168787015260608083015161ffff169087015260808083015182169087015260a091820151169085015260c09093019290850190600101615c64565b600060408284031215615cde57600080fd5b615ce6614b5a565b615cef83615493565b815260208301516155f381614efd565b60208152600061146f60208301846158a6565b60208152600061146f60208301846158ea565b6102208101615da282856001600160a01b03808251168352602082015167ffffffffffffffff808216602086015280604085015116604086015280606085015116606086015250506bffffffffffffffffffffffff60808301511660808401528060a08301511660a08401528060c08301511660c0840152505050565b61146f60e0830184614d9e565b602080825282518282018190526000919060409081850190868401855b8281101561593257815180516001600160a01b031685528681015163ffffffff16878601528581015167ffffffffffffffff908116878701526060808301519091169086015260809081015115159085015260a09093019290850190600101615dcc565b60008251615e42818460208701614a63565b9190910192915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var EVM2EVMOnRampABI = EVM2EVMOnRampMetaData.ABI @@ -2171,7 +2171,7 @@ func (EVM2EVMOnRampConfigSet) Topic() common.Hash { } func (EVM2EVMOnRampFeeConfigSet) Topic() common.Hash { - return common.HexToHash("0x2386f61ab5cafc3fed44f9f614f721ab53479ef64067fd16c1a2491b63ddf1a8") + return common.HexToHash("0x067924bf9277d905a9a4631a06d959bc032ace86b3caa835ae7e403d4f39010e") } func (EVM2EVMOnRampNopPaid) Topic() common.Hash { @@ -2199,7 +2199,7 @@ func (EVM2EVMOnRampPoolRemoved) Topic() common.Hash { } func (EVM2EVMOnRampTokenTransferFeeConfigSet) Topic() common.Hash { - return common.HexToHash("0x3df02211160f78e9bbed13e8bf0752035362a05f0651a5e25007acfb659c3620") + return common.HexToHash("0x555c74101f7a15746d31c6731170310e667bcc607996b2fc0b981a7b26a416e9") } func (_EVM2EVMOnRamp *EVM2EVMOnRamp) Address() common.Address { diff --git a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go index 5713997270..fffe85fbcd 100644 --- a/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go +++ b/core/gethwrappers/ccip/generated/lock_release_token_pool/lock_release_token_pool.go @@ -51,8 +51,8 @@ type TokenPoolRampUpdate struct { } var LockReleaseTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"NonExistentRamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermissionsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"RampAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WithdrawalTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"onRamps\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"offRamps\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"currentOffRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"currentOnRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLockReleaseInterfaceId\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOnRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"}],\"name\":\"getProvidedLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"isOnRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"removeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOffRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOnRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b50604051620036cd380380620036cd833981016040819052620000359162000535565b83838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200013a565b5050506001600160a01b038316620000ed576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808416608052811660a052815115801560c0526200012857604080516000815260208101909152620001289083620001e5565b505050151560e05250620006b9915050565b336001600160a01b03821603620001945760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000206576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200029b5760008382815181106200022a576200022a62000645565b602090810291909101015190506200024460028262000356565b1562000287576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50620002938162000671565b905062000209565b5060005b815181101562000351576000828281518110620002c057620002c062000645565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002ec57506200033e565b620002f960028262000376565b156200033c576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b620003498162000671565b90506200029f565b505050565b60006200036d836001600160a01b0384166200038d565b90505b92915050565b60006200036d836001600160a01b03841662000491565b6000818152600183016020526040812054801562000486576000620003b46001836200068d565b8554909150600090620003ca906001906200068d565b905081811462000436576000866000018281548110620003ee57620003ee62000645565b906000526020600020015490508087600001848154811062000414576200041462000645565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200044a576200044a620006a3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000370565b600091505062000370565b6000818152600183016020526040812054620004da5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000370565b50600062000370565b6001600160a01b0381168114620004f957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200051f81620004e3565b919050565b805180151581146200051f57600080fd5b600080600080608085870312156200054c57600080fd5b84516200055981620004e3565b602086810151919550906001600160401b03808211156200057957600080fd5b818801915088601f8301126200058e57600080fd5b815181811115620005a357620005a3620004fc565b8060051b604051601f19603f83011681018181108582111715620005cb57620005cb620004fc565b60405291825284820192508381018501918b831115620005ea57600080fd5b938501935b828510156200061357620006038562000512565b84529385019392850192620005ef565b8098505050505050506200062a6040860162000512565b91506200063a6060860162000524565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200068657620006866200065b565b5060010190565b818103818111156200037057620003706200065b565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e051612f8d6200074060003960008181610425015261051301526000818161047101528181610b29015261129a015260008181610241015281816109720152610bad0152600081816101e50152818161058201528181610a5901528181610d4401528181610e3b015281816116da01526117770152612f8d6000f3fe608060405234801561001057600080fd5b50600436106101a35760003560e01c806387381314116100ee578063a7cd63b711610097578063c49907b511610071578063c49907b514610449578063d612b9451461045c578063e0351e131461046f578063f2fde38b1461049557600080fd5b8063a7cd63b714610408578063b3a3fb4114610410578063bb98546b1461042357600080fd5b806396875445116100c857806396875445146103cd5780639c8f9f23146103ed578063a40e69c71461040057600080fd5b8063873813141461036c5780638bfca18c146103815780638da5cb5b146103af57600080fd5b806356dd1e81116101505780637787e7ab1161012a5780637787e7ab146102e257806379ba5097146103515780638627fad61461035957600080fd5b806356dd1e81146102785780636f32b872146102bc5780637448b3c7146102cf57600080fd5b806351c6590a1161018157806351c6590a1461022a5780635246492f1461023f57806354c8a4f31461026557600080fd5b806301ffc9a7146101a85780631d7a74a0146101d057806321df0da7146101e3575b600080fd5b6101bb6101b63660046126f8565b6104a8565b60405190151581526020015b60405180910390f35b6101bb6101de366004612763565b610504565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c7565b61023d61023836600461277e565b610511565b005b7f0000000000000000000000000000000000000000000000000000000000000000610205565b61023d6102733660046127e3565b6105fe565b6102ae610286366004612763565b73ffffffffffffffffffffffffffffffffffffffff166000908152600a602052604090205490565b6040519081526020016101c7565b6101bb6102ca366004612763565b610679565b61023d6102dd366004612926565b610686565b6102f56102f0366004612763565b610756565b6040516101c7919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b61023d610834565b61023d610367366004612a1d565b610931565b610374610ad4565b6040516101c79190612aac565b6040517f98a471770000000000000000000000000000000000000000000000000000000081526020016101c7565b60005473ffffffffffffffffffffffffffffffffffffffff16610205565b6103e06103db366004612b48565b610ae5565b6040516101c79190612c54565b61023d6103fb36600461277e565b610ccb565b610374610e92565b610374610e9e565b6102f561041e366004612763565b610eaa565b7f00000000000000000000000000000000000000000000000000000000000000006101bb565b61023d610457366004612cac565b610f88565b61023d61046a366004612926565b610f9c565b7f00000000000000000000000000000000000000000000000000000000000000006101bb565b61023d6104a3366004612763565b61105b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f98a471770000000000000000000000000000000000000000000000000000000014806104fe57506104fe8261106f565b92915050565b60006104fe600783611107565b7f0000000000000000000000000000000000000000000000000000000000000000610568576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105aa73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084611139565b336000908152600a6020526040812080548392906105c9908490612d3b565b9091555050604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b610606611215565b6106738484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061129892505050565b50505050565b60006104fe600483611107565b61068e611215565b61069782610679565b6106ea576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081526006602052604090206107199082611463565b7f578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed6828260405161074a929190612d4e565b60405180910390a15050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260066020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526104fe90611612565b60015473ffffffffffffffffffffffffffffffffffffffff1633146108b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106e1565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61093a33610504565b610970576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109ff9190612da6565b15610a36576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a3f836116c4565b610a8073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001685856116fe565b60405183815273ffffffffffffffffffffffffffffffffffffffff85169033907f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f529060200160405180910390a35050505050565b6060610ae06004611754565b905090565b6060610af033610679565b610b26576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b877f00000000000000000000000000000000000000000000000000000000000000008015610b5c5750610b5a600282611107565b155b15610bab576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016106e1565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c16573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c3a9190612da6565b15610c71576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c7a86611761565b60405186815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a25050604080516020810190915260008152979650505050505050565b336000908152600a6020526040902054811115610d14576040517f6982012000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610da0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc49190612dc3565b1015610dfc576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a602052604081208054839290610e1b908490612ddc565b90915550610e62905073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633836116fe565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6060610ae06007611754565b6060610ae06002611754565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260096020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526104fe90611612565b610f90611215565b6106738484848461179b565b610fa4611215565b610fad82610504565b610ffb576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016106e1565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260096020526040902061102a9082611463565b7fb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f828260405161074a929190612d4e565b611063611215565b61106c81611d4b565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa3340000000000000000000000000000000000000000000000000000000014806104fe57507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526106739085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611e40565b60005473ffffffffffffffffffffffffffffffffffffffff163314611296576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106e1565b565b7f00000000000000000000000000000000000000000000000000000000000000006112ef576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b825181101561138d57600083828151811061130f5761130f612def565b6020026020010151905061132d816002611f4c90919063ffffffff16565b1561137c5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5061138681612e1e565b90506112f2565b5060005b815181101561145e5760008282815181106113ae576113ae612def565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036113f2575061144e565b6113fd600282611f6e565b1561144c5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b61145781612e1e565b9050611391565b505050565b815460009061148c90700100000000000000000000000000000000900463ffffffff1642612ddc565b9050801561152e57600183015483546114d4916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416611f90565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354611554916fffffffffffffffffffffffffffffffff9081169116611fba565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611605908490612e56565b60405180910390a1505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526116a082606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426116849190612ddc565b85608001516fffffffffffffffffffffffffffffffff16611f90565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b33600090815260096020526040902061106c90827f0000000000000000000000000000000000000000000000000000000000000000611fd0565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261145e9084907fa9059cbb0000000000000000000000000000000000000000000000000000000090606401611193565b6060600061113283612353565b33600090815260066020526040902061106c90827f0000000000000000000000000000000000000000000000000000000000000000611fd0565b6117a3611215565b60005b83811015611ac05760008585838181106117c2576117c2612def565b905060a002018036038101906117d89190612e92565b90508060200151156119b05780516117f290600490611f6e565b15611963576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526006909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac926119569291612d4e565b60405180910390a1611aaf565b80516040517fd3eb6bc500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016106e1565b80516119be90600490611f4c565b15611a6257805173ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517f7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b5294916119569173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b80516040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016106e1565b50611ab981612e1e565b90506117a6565b5060005b81811015611d44576000838383818110611ae057611ae0612def565b905060a00201803603810190611af69190612e92565b9050806020015115611c81578051611b1090600790611f6e565b15611963576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526009909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d8892611c749291612d4e565b60405180910390a1611d33565b8051611c8f90600790611f4c565b15611a6257805173ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517fcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c91611c749173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b50611d3d81612e1e565b9050611ac4565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611dca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106e1565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611ea2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123af9092919063ffffffff16565b80519091501561145e5780806020019051810190611ec09190612da6565b61145e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f7420737563636565640000000000000000000000000000000000000000000060648201526084016106e1565b60006111328373ffffffffffffffffffffffffffffffffffffffff84166123be565b60006111328373ffffffffffffffffffffffffffffffffffffffff84166124b1565b6000611faf85611fa08486612ee3565b611faa9087612d3b565b611fba565b90505b949350505050565b6000818310611fc95781611132565b5090919050565b825474010000000000000000000000000000000000000000900460ff161580611ff7575081155b1561200157505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061204790700100000000000000000000000000000000900463ffffffff1642612ddc565b905080156121075781831115612089576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546120c39083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16611f90565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156121be5773ffffffffffffffffffffffffffffffffffffffff8416612166576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106e1565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016106e1565b848310156122d15760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906122029082612ddc565b61220c878a612ddc565b6122169190612d3b565b6122209190612efa565b905073ffffffffffffffffffffffffffffffffffffffff8616612279576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106e1565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016106e1565b6122db8584612ddc565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156123a357602002820191906000526020600020905b81548152602001906001019080831161238f575b50505050509050919050565b6060611fb28484600085612500565b600081815260018301602052604081205480156124a75760006123e2600183612ddc565b85549091506000906123f690600190612ddc565b905081811461245b57600086600001828154811061241657612416612def565b906000526020600020015490508087600001848154811061243957612439612def565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061246c5761246c612f35565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104fe565b60009150506104fe565b60008181526001830160205260408120546124f8575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104fe565b5060006104fe565b606082471015612592576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c000000000000000000000000000000000000000000000000000060648201526084016106e1565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516125bb9190612f64565b60006040518083038185875af1925050503d80600081146125f8576040519150601f19603f3d011682016040523d82523d6000602084013e6125fd565b606091505b509150915061260e87838387612619565b979650505050505050565b606083156126af5782516000036126a85773ffffffffffffffffffffffffffffffffffffffff85163b6126a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016106e1565b5081611fb2565b611fb283838151156126c45781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e19190612c54565b60006020828403121561270a57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461113257600080fd5b803573ffffffffffffffffffffffffffffffffffffffff8116811461275e57600080fd5b919050565b60006020828403121561277557600080fd5b6111328261273a565b60006020828403121561279057600080fd5b5035919050565b60008083601f8401126127a957600080fd5b50813567ffffffffffffffff8111156127c157600080fd5b6020830191508360208260051b85010111156127dc57600080fd5b9250929050565b600080600080604085870312156127f957600080fd5b843567ffffffffffffffff8082111561281157600080fd5b61281d88838901612797565b9096509450602087013591508082111561283657600080fd5b5061284387828801612797565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff811182821017156128a1576128a161284f565b60405290565b801515811461106c57600080fd5b80356fffffffffffffffffffffffffffffffff8116811461275e57600080fd5b6000606082840312156128e757600080fd5b6128ef61287e565b905081356128fc816128a7565b815261290a602083016128b5565b602082015261291b604083016128b5565b604082015292915050565b6000806080838503121561293957600080fd5b6129428361273a565b915061295184602085016128d5565b90509250929050565b600082601f83011261296b57600080fd5b813567ffffffffffffffff808211156129865761298661284f565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156129cc576129cc61284f565b816040528381528660208588010111156129e557600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff8116811461275e57600080fd5b600080600080600060a08688031215612a3557600080fd5b853567ffffffffffffffff80821115612a4d57600080fd5b612a5989838a0161295a565b9650612a676020890161273a565b955060408801359450612a7c60608901612a05565b93506080880135915080821115612a9257600080fd5b50612a9f8882890161295a565b9150509295509295909350565b6020808252825182820181905260009190848201906040850190845b81811015612afa57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612ac8565b50909695505050505050565b60008083601f840112612b1857600080fd5b50813567ffffffffffffffff811115612b3057600080fd5b6020830191508360208285010111156127dc57600080fd5b600080600080600080600060a0888a031215612b6357600080fd5b612b6c8861273a565b9650602088013567ffffffffffffffff80821115612b8957600080fd5b612b958b838c01612b06565b909850965060408a01359550869150612bb060608b01612a05565b945060808a0135915080821115612bc657600080fd5b50612bd38a828b01612b06565b989b979a50959850939692959293505050565b60005b83811015612c01578181015183820152602001612be9565b50506000910152565b60008151808452612c22816020860160208601612be6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006111326020830184612c0a565b60008083601f840112612c7957600080fd5b50813567ffffffffffffffff811115612c9157600080fd5b60208301915083602060a0830285010111156127dc57600080fd5b60008060008060408587031215612cc257600080fd5b843567ffffffffffffffff80821115612cda57600080fd5b612ce688838901612c67565b90965094506020870135915080821115612cff57600080fd5b5061284387828801612c67565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104fe576104fe612d0c565b73ffffffffffffffffffffffffffffffffffffffff831681526080810161113260208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215612db857600080fd5b8151611132816128a7565b600060208284031215612dd557600080fd5b5051919050565b818103818111156104fe576104fe612d0c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e4f57612e4f612d0c565b5060010190565b606081016104fe82848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060a08284031215612ea457600080fd5b612eac61287e565b612eb58361273a565b81526020830135612ec5816128a7565b6020820152612ed784604085016128d5565b60408201529392505050565b80820281158282048414176104fe576104fe612d0c565b600082612f30577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612f76818460208701612be6565b919091019291505056fea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"acceptLiquidity\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientLiquidity\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LiquidityNotAccepted\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"NonExistentRamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermissionsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"RampAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WithdrawalTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"LiquidityRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"addLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"onRamps\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"offRamps\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"canAcceptLiquidity\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"currentOffRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"currentOnRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getLockReleaseInterfaceId\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOnRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"provider\",\"type\":\"address\"}],\"name\":\"getProvidedLiquidity\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"isOnRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"removeLiquidity\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOffRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOnRampRateLimiterConfig\",\"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\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200371438038062003714833981016040819052620000359162000535565b83838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c2816200013a565b5050506001600160a01b038316620000ed576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808416608052811660a052815115801560c0526200012857604080516000815260208101909152620001289083620001e5565b505050151560e05250620006b9915050565b336001600160a01b03821603620001945760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c05162000206576040516335f4a7b360e01b815260040160405180910390fd5b60005b82518110156200029b5760008382815181106200022a576200022a62000645565b602090810291909101015190506200024460028262000356565b1562000287576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50620002938162000671565b905062000209565b5060005b815181101562000351576000828281518110620002c057620002c062000645565b6020026020010151905060006001600160a01b0316816001600160a01b031603620002ec57506200033e565b620002f960028262000376565b156200033c576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b620003498162000671565b90506200029f565b505050565b60006200036d836001600160a01b0384166200038d565b90505b92915050565b60006200036d836001600160a01b03841662000491565b6000818152600183016020526040812054801562000486576000620003b46001836200068d565b8554909150600090620003ca906001906200068d565b905081811462000436576000866000018281548110620003ee57620003ee62000645565b906000526020600020015490508087600001848154811062000414576200041462000645565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806200044a576200044a620006a3565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505062000370565b600091505062000370565b6000818152600183016020526040812054620004da5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000370565b50600062000370565b6001600160a01b0381168114620004f957600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b80516200051f81620004e3565b919050565b805180151581146200051f57600080fd5b600080600080608085870312156200054c57600080fd5b84516200055981620004e3565b602086810151919550906001600160401b03808211156200057957600080fd5b818801915088601f8301126200058e57600080fd5b815181811115620005a357620005a3620004fc565b8060051b604051601f19603f83011681018181108582111715620005cb57620005cb620004fc565b60405291825284820192508381018501918b831115620005ea57600080fd5b938501935b828510156200061357620006038562000512565b84529385019392850192620005ef565b8098505050505050506200062a6040860162000512565b91506200063a6060860162000524565b905092959194509250565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016200068657620006866200065b565b5060010190565b818103818111156200037057620003706200065b565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e051612fd4620007406000396000818161046c015261055a0152600081816104b801528181610b7001526112e1015260008181610295015281816109b90152610bf4015260008181610239015281816105c901528181610aa001528181610d8b01528181610e820152818161172101526117be0152612fd46000f3fe608060405234801561001057600080fd5b50600436106101ae5760003560e01c806387381314116100ee578063a7cd63b711610097578063c49907b511610071578063c49907b514610490578063d612b945146104a3578063e0351e13146104b6578063f2fde38b146104dc57600080fd5b8063a7cd63b71461044f578063b3a3fb4114610457578063bb98546b1461046a57600080fd5b806396875445116100c857806396875445146104215780639c8f9f2314610434578063a40e69c71461044757600080fd5b806387381314146103c05780638bfca18c146103d55780638da5cb5b1461040357600080fd5b806354c8a4f31161015b5780637448b3c7116101355780637448b3c7146103235780637787e7ab1461033657806379ba5097146103a55780638627fad6146103ad57600080fd5b806354c8a4f3146102b957806356dd1e81146102cc5780636f32b8721461031057600080fd5b806321df0da71161018c57806321df0da71461023757806351c6590a1461027e5780635246492f1461029357600080fd5b806301ffc9a7146101b3578063181f5a77146101db5780631d7a74a014610224575b600080fd5b6101c66101c136600461273f565b6104ef565b60405190151581526020015b60405180910390f35b6102176040518060400160405280601a81526020017f4c6f636b52656c65617365546f6b656e506f6f6c20312e322e3000000000000081525081565b6040516101d291906127ef565b6101c661023236600461282b565b61054b565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b61029161028c366004612846565b610558565b005b7f0000000000000000000000000000000000000000000000000000000000000000610259565b6102916102c73660046128ab565b610645565b6103026102da36600461282b565b73ffffffffffffffffffffffffffffffffffffffff166000908152600a602052604090205490565b6040519081526020016101d2565b6101c661031e36600461282b565b6106c0565b6102916103313660046129ee565b6106cd565b61034961034436600461282b565b61079d565b6040516101d2919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b61029161087b565b6102916103bb366004612ae5565b610978565b6103c8610b1b565b6040516101d29190612b74565b6040517f98a471770000000000000000000000000000000000000000000000000000000081526020016101d2565b60005473ffffffffffffffffffffffffffffffffffffffff16610259565b61021761042f366004612c10565b610b2c565b610291610442366004612846565b610d12565b6103c8610ed9565b6103c8610ee5565b61034961046536600461282b565b610ef1565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b61029161049e366004612cf3565b610fcf565b6102916104b13660046129ee565b610fe3565b7f00000000000000000000000000000000000000000000000000000000000000006101c6565b6102916104ea36600461282b565b6110a2565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f98a471770000000000000000000000000000000000000000000000000000000014806105455750610545826110b6565b92915050565b600061054560078361114e565b7f00000000000000000000000000000000000000000000000000000000000000006105af576040517fe93f8fa400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105f173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084611180565b336000908152600a602052604081208054839290610610908490612d82565b9091555050604051819033907fc17cea59c2955cb181b03393209566960365771dbba9dc3d510180e7cb31208890600090a350565b61064d61125c565b6106ba848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506112df92505050565b50505050565b600061054560048361114e565b6106d561125c565b6106de826106c0565b610731576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216600090815260066020526040902061076090826114aa565b7f578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed68282604051610791929190612d95565b60405180910390a15050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260066020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261054590611659565b60015473ffffffffffffffffffffffffffffffffffffffff1633146108fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610728565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6109813361054b565b6109b7576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a469190612ded565b15610a7d576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a868361170b565b610ac773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168585611745565b60405183815273ffffffffffffffffffffffffffffffffffffffff85169033907f2d87480f50083e2b2759522a8fdda59802650a8055e609a7772cf70c07748f529060200160405180910390a35050505050565b6060610b27600461179b565b905090565b6060610b37336106c0565b610b6d576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b877f00000000000000000000000000000000000000000000000000000000000000008015610ba35750610ba160028261114e565b155b15610bf2576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152602401610728565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663397796f76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c819190612ded565b15610cb8576040517fc148371500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610cc1866117a8565b60405186815233907f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd600089060200160405180910390a25050604080516020810190915260008152979650505050505050565b336000908152600a6020526040902054811115610d5b576040517f6982012000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015281907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015610de7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0b9190612e0a565b1015610e43576040517fbb55fd2700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600a602052604081208054839290610e62908490612e23565b90915550610ea9905073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163383611745565b604051819033907fc2c3f06e49b9f15e7b4af9055e183b0d73362e033ad82a07dec9bf984017171990600090a350565b6060610b27600761179b565b6060610b27600261179b565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260096020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261054590611659565b610fd761125c565b6106ba848484846117e2565b610feb61125c565b610ff48261054b565b611042576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83166004820152602401610728565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260096020526040902061107190826114aa565b7fb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f8282604051610791929190612d95565b6110aa61125c565b6110b381611d92565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa33400000000000000000000000000000000000000000000000000000000148061054557507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526106ba9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152611e87565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610728565b565b7f0000000000000000000000000000000000000000000000000000000000000000611336576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156113d457600083828151811061135657611356612e36565b60200260200101519050611374816002611f9390919063ffffffff16565b156113c35760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506113cd81612e65565b9050611339565b5060005b81518110156114a55760008282815181106113f5576113f5612e36565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036114395750611495565b611444600282611fb5565b156114935760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b61149e81612e65565b90506113d8565b505050565b81546000906114d390700100000000000000000000000000000000900463ffffffff1642612e23565b90508015611575576001830154835461151b916fffffffffffffffffffffffffffffffff80821692811691859170010000000000000000000000000000000090910416611fd7565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b6020820151835461159b916fffffffffffffffffffffffffffffffff9081169116612001565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c199061164c908490612e9d565b60405180910390a1505050565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526116e782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff16426116cb9190612e23565b85608001516fffffffffffffffffffffffffffffffff16611fd7565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b3360009081526009602052604090206110b390827f0000000000000000000000000000000000000000000000000000000000000000612017565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526114a59084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016111da565b606060006111798361239a565b3360009081526006602052604090206110b390827f0000000000000000000000000000000000000000000000000000000000000000612017565b6117ea61125c565b60005b83811015611b0757600085858381811061180957611809612e36565b905060a0020180360381019061181f9190612ed9565b90508060200151156119f757805161183990600490611fb5565b156119aa576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526006909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac9261199d9291612d95565b60405180910390a1611af6565b80516040517fd3eb6bc500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610728565b8051611a0590600490611f93565b15611aa957805173ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517f7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b52949161199d9173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b80516040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401610728565b50611b0081612e65565b90506117ed565b5060005b81811015611d8b576000838383818110611b2757611b27612e36565b905060a00201803603810190611b3d9190612ed9565b9050806020015115611cc8578051611b5790600790611fb5565b156119aa576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526009909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d8892611cbb9291612d95565b60405180910390a1611d7a565b8051611cd690600790611f93565b15611aa957805173ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517fcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c91611cbb9173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b50611d8481612e65565b9050611b0b565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603611e11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610728565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000611ee9826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123f69092919063ffffffff16565b8051909150156114a55780806020019051810190611f079190612ded565b6114a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610728565b60006111798373ffffffffffffffffffffffffffffffffffffffff8416612405565b60006111798373ffffffffffffffffffffffffffffffffffffffff84166124f8565b6000611ff685611fe78486612f2a565b611ff19087612d82565b612001565b90505b949350505050565b60008183106120105781611179565b5090919050565b825474010000000000000000000000000000000000000000900460ff16158061203e575081155b1561204857505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061208e90700100000000000000000000000000000000900463ffffffff1642612e23565b9050801561214e57818311156120d0576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461210a9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff16611fd7565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156122055773ffffffffffffffffffffffffffffffffffffffff84166121ad576040517ff94ebcd10000000000000000000000000000000000000000000000000000000081526004810183905260248101869052604401610728565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff85166044820152606401610728565b848310156123185760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff169060009082906122499082612e23565b612253878a612e23565b61225d9190612d82565b6122679190612f41565b905073ffffffffffffffffffffffffffffffffffffffff86166122c0576040517f15279c080000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610728565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff87166044820152606401610728565b6123228584612e23565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156123ea57602002820191906000526020600020905b8154815260200190600101908083116123d6575b50505050509050919050565b6060611ff98484600085612547565b600081815260018301602052604081205480156124ee576000612429600183612e23565b855490915060009061243d90600190612e23565b90508181146124a257600086600001828154811061245d5761245d612e36565b906000526020600020015490508087600001848154811061248057612480612e36565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806124b3576124b3612f7c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610545565b6000915050610545565b600081815260018301602052604081205461253f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610545565b506000610545565b6060824710156125d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610728565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516126029190612fab565b60006040518083038185875af1925050503d806000811461263f576040519150601f19603f3d011682016040523d82523d6000602084013e612644565b606091505b509150915061265587838387612660565b979650505050505050565b606083156126f65782516000036126ef5773ffffffffffffffffffffffffffffffffffffffff85163b6126ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610728565b5081611ff9565b611ff9838381511561270b5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072891906127ef565b60006020828403121561275157600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461117957600080fd5b60005b8381101561279c578181015183820152602001612784565b50506000910152565b600081518084526127bd816020860160208601612781565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061117960208301846127a5565b803573ffffffffffffffffffffffffffffffffffffffff8116811461282657600080fd5b919050565b60006020828403121561283d57600080fd5b61117982612802565b60006020828403121561285857600080fd5b5035919050565b60008083601f84011261287157600080fd5b50813567ffffffffffffffff81111561288957600080fd5b6020830191508360208260051b85010111156128a457600080fd5b9250929050565b600080600080604085870312156128c157600080fd5b843567ffffffffffffffff808211156128d957600080fd5b6128e58883890161285f565b909650945060208701359150808211156128fe57600080fd5b5061290b8782880161285f565b95989497509550505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561296957612969612917565b60405290565b80151581146110b357600080fd5b80356fffffffffffffffffffffffffffffffff8116811461282657600080fd5b6000606082840312156129af57600080fd5b6129b7612946565b905081356129c48161296f565b81526129d26020830161297d565b60208201526129e36040830161297d565b604082015292915050565b60008060808385031215612a0157600080fd5b612a0a83612802565b9150612a19846020850161299d565b90509250929050565b600082601f830112612a3357600080fd5b813567ffffffffffffffff80821115612a4e57612a4e612917565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715612a9457612a94612917565b81604052838152866020858801011115612aad57600080fd5b836020870160208301376000602085830101528094505050505092915050565b803567ffffffffffffffff8116811461282657600080fd5b600080600080600060a08688031215612afd57600080fd5b853567ffffffffffffffff80821115612b1557600080fd5b612b2189838a01612a22565b9650612b2f60208901612802565b955060408801359450612b4460608901612acd565b93506080880135915080821115612b5a57600080fd5b50612b6788828901612a22565b9150509295509295909350565b6020808252825182820181905260009190848201906040850190845b81811015612bc257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612b90565b50909695505050505050565b60008083601f840112612be057600080fd5b50813567ffffffffffffffff811115612bf857600080fd5b6020830191508360208285010111156128a457600080fd5b600080600080600080600060a0888a031215612c2b57600080fd5b612c3488612802565b9650602088013567ffffffffffffffff80821115612c5157600080fd5b612c5d8b838c01612bce565b909850965060408a01359550869150612c7860608b01612acd565b945060808a0135915080821115612c8e57600080fd5b50612c9b8a828b01612bce565b989b979a50959850939692959293505050565b60008083601f840112612cc057600080fd5b50813567ffffffffffffffff811115612cd857600080fd5b60208301915083602060a0830285010111156128a457600080fd5b60008060008060408587031215612d0957600080fd5b843567ffffffffffffffff80821115612d2157600080fd5b612d2d88838901612cae565b90965094506020870135915080821115612d4657600080fd5b5061290b87828801612cae565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561054557610545612d53565b73ffffffffffffffffffffffffffffffffffffffff831681526080810161117960208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060208284031215612dff57600080fd5b81516111798161296f565b600060208284031215612e1c57600080fd5b5051919050565b8181038181111561054557610545612d53565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612e9657612e96612d53565b5060010190565b6060810161054582848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060a08284031215612eeb57600080fd5b612ef3612946565b612efc83612802565b81526020830135612f0c8161296f565b6020820152612f1e846040850161299d565b60408201529392505050565b808202811582820484141761054557610545612d53565b600082612f77577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251612fbd818460208701612781565b919091019291505056fea164736f6c6343000813000a", } var LockReleaseTokenPoolABI = LockReleaseTokenPoolMetaData.ABI @@ -521,6 +521,28 @@ func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) SupportsInterfac return _LockReleaseTokenPool.Contract.SupportsInterface(&_LockReleaseTokenPool.CallOpts, interfaceId) } +func (_LockReleaseTokenPool *LockReleaseTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _LockReleaseTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolSession) TypeAndVersion() (string, error) { + return _LockReleaseTokenPool.Contract.TypeAndVersion(&_LockReleaseTokenPool.CallOpts) +} + +func (_LockReleaseTokenPool *LockReleaseTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _LockReleaseTokenPool.Contract.TypeAndVersion(&_LockReleaseTokenPool.CallOpts) +} + func (_LockReleaseTokenPool *LockReleaseTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { return _LockReleaseTokenPool.contract.Transact(opts, "acceptOwnership") } @@ -2794,6 +2816,8 @@ type LockReleaseTokenPoolInterface interface { SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + TypeAndVersion(opts *bind.CallOpts) (string, error) + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) AddLiquidity(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generated/price_registry/price_registry.go b/core/gethwrappers/ccip/generated/price_registry/price_registry.go index 5e339fa855..b42e532150 100644 --- a/core/gethwrappers/ccip/generated/price_registry/price_registry.go +++ b/core/gethwrappers/ccip/generated/price_registry/price_registry.go @@ -30,12 +30,16 @@ var ( _ = abi.ConvertType ) -type InternalPriceUpdates struct { - TokenPriceUpdates []InternalTokenPriceUpdate +type InternalGasPriceUpdate struct { DestChainSelector uint64 UsdPerUnitGas *big.Int } +type InternalPriceUpdates struct { + TokenPriceUpdates []InternalTokenPriceUpdate + GasPriceUpdates []InternalGasPriceUpdate +} + type InternalTimestampedPackedUint224 struct { Value *big.Int Timestamp uint32 @@ -47,8 +51,8 @@ type InternalTokenPriceUpdate struct { } var PriceRegistryMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStalenessThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpdaterOrOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleTokenPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"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\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToRemove\",\"type\":\"address[]\"}],\"name\":\"applyPriceUpdatersUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceUpdaters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStalenessThreshold\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"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\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162002280380380620022808339810160408190526200003491620006fe565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000133565b5050604080516000815260208101909152620000dd91508490620001de565b604080516000815260208101909152620000f99083906200033a565b8063ffffffff166000036200012157604051631151410960e11b815260040160405180910390fd5b63ffffffff1660805250620007fa9050565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b825181101562000289576200021d83828151811062000204576200020462000786565b602002602001015160046200049160201b90919060201c565b15620002765782818151811062000238576200023862000786565b60200260200101516001600160a01b03167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b6200028181620007b2565b9050620001e1565b5060005b81518110156200033557620002c9828281518110620002b057620002b062000786565b60200260200101516004620004b160201b90919060201c565b156200032257818181518110620002e457620002e462000786565b60200260200101516001600160a01b03167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b6200032d81620007b2565b90506200028d565b505050565b60005b8251811015620003e5576200037983828151811062000360576200036062000786565b602002602001015160066200049160201b90919060201c565b15620003d25782818151811062000394576200039462000786565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b620003dd81620007b2565b90506200033d565b5060005b81518110156200033557620004258282815181106200040c576200040c62000786565b60200260200101516006620004b160201b90919060201c565b156200047e5781818151811062000440576200044062000786565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6200048981620007b2565b9050620003e9565b6000620004a8836001600160a01b038416620004c8565b90505b92915050565b6000620004a8836001600160a01b0384166200051a565b60008181526001830160205260408120546200051157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004ab565b506000620004ab565b600081815260018301602052604081205480156200061357600062000541600183620007ce565b85549091506000906200055790600190620007ce565b9050818114620005c35760008660000182815481106200057b576200057b62000786565b9060005260206000200154905080876000018481548110620005a157620005a162000786565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005d757620005d7620007e4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004ab565b6000915050620004ab565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200064c57600080fd5b919050565b600082601f8301126200066357600080fd5b815160206001600160401b03808311156200068257620006826200061e565b8260051b604051601f19603f83011681018181108482111715620006aa57620006aa6200061e565b604052938452858101830193838101925087851115620006c957600080fd5b83870191505b84821015620006f357620006e38262000634565b83529183019190830190620006cf565b979650505050505050565b6000806000606084860312156200071457600080fd5b83516001600160401b03808211156200072c57600080fd5b6200073a8783880162000651565b945060208601519150808211156200075157600080fd5b50620007608682870162000651565b925050604084015163ffffffff811681146200077b57600080fd5b809150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620007c757620007c76200079c565b5060010190565b81810381811115620004ab57620004ab6200079c565b634e487b7160e01b600052603160045260246000fd5b608051611a4e62000832600039600081816102eb01528181610ae101528181610b4a01528181610cab0152610d200152611a4e6000f3fe608060405234801561001057600080fd5b50600436106100ff5760003560e01c80638da5cb5b11610097578063cdc73d5111610066578063cdc73d511461032a578063d02641a014610332578063f2fde38b146103d4578063ffdb4b37146103e757600080fd5b80638da5cb5b146102a657806398f5be1b146102ce578063a6c94a73146102e1578063bfcd45661461031557600080fd5b8063514e8cff116100d3578063514e8cff146101d357806352877af01461027657806379ba50971461028b5780637afac3221461029357600080fd5b806241e5be14610104578063181f5a771461012a57806345ac924d146101735780634ab35b0b14610193575b600080fd5b6101176101123660046113d1565b61042f565b6040519081526020015b60405180910390f35b6101666040518060400160405280601381526020017f5072696365526567697374727920312e322e300000000000000000000000000081525081565b604051610121919061140d565b610186610181366004611479565b61049b565b60405161012191906114ee565b6101a66101a1366004611569565b61056f565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b6102696101e136600461159c565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b60405161012191906115b7565b6102896102843660046116e1565b61057a565b005b610289610590565b6102896102a13660046116e1565b610692565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b6102896102dc366004611745565b6106a4565b60405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610121565b61031d6109dc565b6040516101219190611780565b61031d6109ed565b610269610340366004611569565b60408051808201909152600080825260208201525073ffffffffffffffffffffffffffffffffffffffff166000908152600360209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6102896103e2366004611569565b6109f9565b6103fa6103f53660046117da565b610a0d565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff938416815292909116602083015201610121565b600061043a82610b98565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661046185610b98565b610489907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168561183c565b6104939190611853565b949350505050565b60608160008167ffffffffffffffff8111156104b9576104b96115f2565b6040519080825280602002602001820160405280156104fe57816020015b60408051808201909152600080825260208201528152602001906001900390816104d75790505b50905060005b82811015610564576105368686838181106105215761052161188e565b90506020020160208101906103409190611569565b8282815181106105485761054861188e565b60200260200101819052508061055d906118bd565b9050610504565b509150505b92915050565b600061056982610b98565b610582610d5c565b61058c8282610ddf565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610616576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61069a610d5c565b61058c8282610f3b565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906106d457506106d2600433611092565b155b1561070b576040517f46f0815400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061071782806118f5565b9050905060005b8181101561086957600061073284806118f5565b838181106107425761074261188e565b9050604002018036038101906107589190611989565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600390975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926108509290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250610862816118bd565b905061071e565b5061087a604083016020840161159c565b67ffffffffffffffff161561058c5760405180604001604052808360400160208101906108a791906119e4565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681526020014263ffffffff16815250600260008460200160208101906108eb919061159c565b67ffffffffffffffff168152602080820192909252604090810160002083519383015163ffffffff167c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9094169390931790925561096891840190840161159c565b67ffffffffffffffff167fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e6109a360608501604086016119e4565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90921682524260208301520160405180910390a25050565b60606109e860046110c4565b905090565b60606109e860066110c4565b610a01610d5c565b610a0a816110d1565b50565b67ffffffffffffffff811660009081526002602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203610ac5576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8516600482015260240161060d565b6000816020015163ffffffff1642610add91906119ff565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610b7e576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044810182905260640161060d565b610b8786610b98565b9151919350909150505b9250929050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff16918101829052901580610c40575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15610c8f576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8416600482015260240161060d565b6000816020015163ffffffff1642610ca791906119ff565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610d54576040517fc65fdfca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015263ffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044810182905260640161060d565b505192915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610ddd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161060d565b565b60005b8251811015610e8a57610e18838281518110610e0057610e0061188e565b602002602001015160046111c690919063ffffffff16565b15610e7a57828181518110610e2f57610e2f61188e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b610e83816118bd565b9050610de2565b5060005b8151811015610f3657610ec4828281518110610eac57610eac61188e565b602002602001015160046111e890919063ffffffff16565b15610f2657818181518110610edb57610edb61188e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b610f2f816118bd565b9050610e8e565b505050565b60005b8251811015610fe657610f74838281518110610f5c57610f5c61188e565b602002602001015160066111c690919063ffffffff16565b15610fd657828181518110610f8b57610f8b61188e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b610fdf816118bd565b9050610f3e565b5060005b8151811015610f36576110208282815181106110085761100861188e565b602002602001015160066111e890919063ffffffff16565b15611082578181815181106110375761103761188e565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b61108b816118bd565b9050610fea565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b606060006110bd8361120a565b3373ffffffffffffffffffffffffffffffffffffffff821603611150576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161060d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006110bd8373ffffffffffffffffffffffffffffffffffffffff8416611266565b60006110bd8373ffffffffffffffffffffffffffffffffffffffff84166112b5565b60608160000180548060200260200160405190810160405280929190818152602001828054801561125a57602002820191906000526020600020905b815481526020019060010190808311611246575b50505050509050919050565b60008181526001830160205260408120546112ad57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610569565b506000610569565b6000818152600183016020526040812054801561139e5760006112d96001836119ff565b85549091506000906112ed906001906119ff565b905081811461135257600086600001828154811061130d5761130d61188e565b90600052602060002001549050808760000184815481106113305761133061188e565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061136357611363611a12565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610569565b6000915050610569565b803573ffffffffffffffffffffffffffffffffffffffff811681146113cc57600080fd5b919050565b6000806000606084860312156113e657600080fd5b6113ef846113a8565b925060208401359150611404604085016113a8565b90509250925092565b600060208083528351808285015260005b8181101561143a5785810183015185820160400152820161141e565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b6000806020838503121561148c57600080fd5b823567ffffffffffffffff808211156114a457600080fd5b818501915085601f8301126114b857600080fd5b8135818111156114c757600080fd5b8660208260051b85010111156114dc57600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b8281101561155c5761154c84835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b928401929085019060010161150b565b5091979650505050505050565b60006020828403121561157b57600080fd5b6110bd826113a8565b803567ffffffffffffffff811681146113cc57600080fd5b6000602082840312156115ae57600080fd5b6110bd82611584565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff169082015260408101610569565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261163257600080fd5b8135602067ffffffffffffffff8083111561164f5761164f6115f2565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715611692576116926115f2565b6040529384528581018301938381019250878511156116b057600080fd5b83870191505b848210156116d6576116c7826113a8565b835291830191908301906116b6565b979650505050505050565b600080604083850312156116f457600080fd5b823567ffffffffffffffff8082111561170c57600080fd5b61171886838701611621565b9350602085013591508082111561172e57600080fd5b5061173b85828601611621565b9150509250929050565b60006020828403121561175757600080fd5b813567ffffffffffffffff81111561176e57600080fd5b8201606081850312156110bd57600080fd5b6020808252825182820181905260009190848201906040850190845b818110156117ce57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161179c565b50909695505050505050565b600080604083850312156117ed57600080fd5b6117f6836113a8565b915061180460208401611584565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820281158282048414176105695761056961180d565b600082611889577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036118ee576118ee61180d565b5060010190565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261192a57600080fd5b83018035915067ffffffffffffffff82111561194557600080fd5b6020019150600681901b3603821315610b9157600080fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146113cc57600080fd5b60006040828403121561199b57600080fd5b6040516040810181811067ffffffffffffffff821117156119be576119be6115f2565b6040526119ca836113a8565b81526119d86020840161195d565b60208201529392505050565b6000602082840312156119f657600080fd5b6110bd8261195d565b818103818111156105695761056961180d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdaters\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokens\",\"type\":\"address[]\"},{\"internalType\":\"uint32\",\"name\":\"stalenessThreshold\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chain\",\"type\":\"uint64\"}],\"name\":\"ChainNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidStalenessThreshold\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableByUpdaterOrOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleGasPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"threshold\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"timePassed\",\"type\":\"uint256\"}],\"name\":\"StaleTokenPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenNotSupported\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"feeToken\",\"type\":\"address\"}],\"name\":\"FeeTokenRemoved\",\"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\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"priceUpdater\",\"type\":\"address\"}],\"name\":\"PriceUpdaterSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerTokenUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChain\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"timestamp\",\"type\":\"uint256\"}],\"name\":\"UsdPerUnitGasUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"feeTokensToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"feeTokensToRemove\",\"type\":\"address[]\"}],\"name\":\"applyFeeTokensUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToAdd\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"priceUpdatersToRemove\",\"type\":\"address[]\"}],\"name\":\"applyPriceUpdatersUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"fromToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fromTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"toToken\",\"type\":\"address\"}],\"name\":\"convertTokenAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getDestinationChainGasPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeTokens\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPriceUpdaters\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getStalenessThreshold\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"}],\"name\":\"getTokenAndGasPrices\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"tokenPrice\",\"type\":\"uint224\"},{\"internalType\":\"uint224\",\"name\":\"gasPriceValue\",\"type\":\"uint224\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getTokenPrice\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"tokens\",\"type\":\"address[]\"}],\"name\":\"getTokenPrices\",\"outputs\":[{\"components\":[{\"internalType\":\"uint224\",\"name\":\"value\",\"type\":\"uint224\"},{\"internalType\":\"uint32\",\"name\":\"timestamp\",\"type\":\"uint32\"}],\"internalType\":\"structInternal.TimestampedPackedUint224[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"getValidatedTokenPrice\",\"outputs\":[{\"internalType\":\"uint224\",\"name\":\"\",\"type\":\"uint224\"}],\"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\":[{\"components\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"sourceToken\",\"type\":\"address\"},{\"internalType\":\"uint224\",\"name\":\"usdPerToken\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.TokenPriceUpdate[]\",\"name\":\"tokenPriceUpdates\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint224\",\"name\":\"usdPerUnitGas\",\"type\":\"uint224\"}],\"internalType\":\"structInternal.GasPriceUpdate[]\",\"name\":\"gasPriceUpdates\",\"type\":\"tuple[]\"}],\"internalType\":\"structInternal.PriceUpdates\",\"name\":\"priceUpdates\",\"type\":\"tuple\"}],\"name\":\"updatePrices\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200227f3803806200227f8339810160408190526200003491620006fe565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be8162000133565b5050604080516000815260208101909152620000dd91508490620001de565b604080516000815260208101909152620000f99083906200033a565b8063ffffffff166000036200012157604051631151410960e11b815260040160405180910390fd5b63ffffffff1660805250620007fa9050565b336001600160a01b038216036200018d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005b825181101562000289576200021d83828151811062000204576200020462000786565b602002602001015160046200049160201b90919060201c565b15620002765782818151811062000238576200023862000786565b60200260200101516001600160a01b03167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b6200028181620007b2565b9050620001e1565b5060005b81518110156200033557620002c9828281518110620002b057620002b062000786565b60200260200101516004620004b160201b90919060201c565b156200032257818181518110620002e457620002e462000786565b60200260200101516001600160a01b03167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b6200032d81620007b2565b90506200028d565b505050565b60005b8251811015620003e5576200037983828151811062000360576200036062000786565b602002602001015160066200049160201b90919060201c565b15620003d25782818151811062000394576200039462000786565b60200260200101516001600160a01b03167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b620003dd81620007b2565b90506200033d565b5060005b81518110156200033557620004258282815181106200040c576200040c62000786565b60200260200101516006620004b160201b90919060201c565b156200047e5781818151811062000440576200044062000786565b60200260200101516001600160a01b03167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6200048981620007b2565b9050620003e9565b6000620004a8836001600160a01b038416620004c8565b90505b92915050565b6000620004a8836001600160a01b0384166200051a565b60008181526001830160205260408120546200051157508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620004ab565b506000620004ab565b600081815260018301602052604081205480156200061357600062000541600183620007ce565b85549091506000906200055790600190620007ce565b9050818114620005c35760008660000182815481106200057b576200057b62000786565b9060005260206000200154905080876000018481548110620005a157620005a162000786565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620005d757620005d7620007e4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050620004ab565b6000915050620004ab565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b03811681146200064c57600080fd5b919050565b600082601f8301126200066357600080fd5b815160206001600160401b03808311156200068257620006826200061e565b8260051b604051601f19603f83011681018181108482111715620006aa57620006aa6200061e565b604052938452858101830193838101925087851115620006c957600080fd5b83870191505b84821015620006f357620006e38262000634565b83529183019190830190620006cf565b979650505050505050565b6000806000606084860312156200071457600080fd5b83516001600160401b03808211156200072c57600080fd5b6200073a8783880162000651565b945060208601519150808211156200075157600080fd5b50620007608682870162000651565b925050604084015163ffffffff811681146200077b57600080fd5b809150509250925092565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600060018201620007c757620007c76200079c565b5060010190565b81810381811115620004ab57620004ab6200079c565b634e487b7160e01b600052603160045260246000fd5b608051611a4d62000832600039600081816102eb01528181610acd01528181610b3601528181610c970152610d0c0152611a4d6000f3fe608060405234801561001057600080fd5b50600436106100ff5760003560e01c80637afac32211610097578063cdc73d5111610066578063cdc73d511461032a578063d02641a014610332578063f2fde38b146103d4578063ffdb4b37146103e757600080fd5b80637afac322146102a65780638da5cb5b146102b9578063a6c94a73146102e1578063bfcd45661461031557600080fd5b80634ab35b0b116100d35780634ab35b0b146101a8578063514e8cff146101e857806352877af01461028b57806379ba50971461029e57600080fd5b806241e5be14610104578063181f5a771461012a5780633937306f1461017357806345ac924d14610188575b600080fd5b6101176101123660046113bd565b61042f565b6040519081526020015b60405180910390f35b6101666040518060400160405280601381526020017f5072696365526567697374727920312e322e300000000000000000000000000081525081565b60405161012191906113f9565b610186610181366004611465565b61049b565b005b61019b6101963660046114a0565b6107bf565b6040516101219190611515565b6101bb6101b6366004611590565b610893565b6040517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b61027e6101f63660046115c3565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600260209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b60405161012191906115de565b610186610299366004611731565b61089e565b6101866108b4565b6101866102b4366004611731565b6109b6565b60005460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b60405163ffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610121565b61031d6109c8565b6040516101219190611795565b61031d6109d9565b61027e610340366004611590565b60408051808201909152600080825260208201525073ffffffffffffffffffffffffffffffffffffffff166000908152600360209081526040918290208251808401909352547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811683527c0100000000000000000000000000000000000000000000000000000000900463ffffffff169082015290565b6101866103e2366004611590565b6109e5565b6103fa6103f53660046117ef565b6109f9565b604080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff938416815292909116602083015201610121565b600061043a82610b84565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1661046185610b84565b610489907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1685611851565b6104939190611868565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906104cb57506104c9600433610d48565b155b15610502576040517f46f0815400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061050e82806118a3565b9050905060005b8181101561066057600061052984806118a3565b838181106105395761053961190b565b90506040020180360381019061054f9190611966565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885173ffffffffffffffffffffffffffffffffffffffff9081166000908152600390975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927f52f50aa6d1a95a4595361ecf953d095f125d442e4673716dede699e049de148a926106479290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a250610659816119a3565b9050610515565b50600061067060208401846118a3565b9050905060005b818110156107b957600061068e60208601866118a3565b8381811061069e5761069e61190b565b9050604002018036038101906106b491906119db565b604080518082018252602080840180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff908116845263ffffffff42818116858701908152885167ffffffffffffffff9081166000908152600290975295889020965190519092167c010000000000000000000000000000000000000000000000000000000002919092161790935584519051935194955016927fdd84a3fa9ef9409f550d54d6affec7e9c480c878c6ab27b78912a03e1b371c6e926107a09290917bffffffffffffffffffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b60405180910390a2506107b2816119a3565b9050610677565b50505050565b60608160008167ffffffffffffffff8111156107dd576107dd611619565b60405190808252806020026020018201604052801561082257816020015b60408051808201909152600080825260208201528152602001906001900390816107fb5790505b50905060005b828110156108885761085a8686838181106108455761084561190b565b90506020020160208101906103409190611590565b82828151811061086c5761086c61190b565b602002602001018190525080610881906119a3565b9050610828565b509150505b92915050565b600061088d82610b84565b6108a6610d7a565b6108b08282610dfd565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461093a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6109be610d7a565b6108b08282610f59565b60606109d460046110b0565b905090565b60606109d460066110b0565b6109ed610d7a565b6109f6816110bd565b50565b67ffffffffffffffff811660009081526002602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff1691810182905282918203610ab1576040517f2e59db3a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff85166004820152602401610931565b6000816020015163ffffffff1642610ac991906119fe565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610b6a576040517ff08bcb3e00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff8616600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610931565b610b7386610b84565b9151919350909150505b9250929050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526003602090815260408083208151808301909252547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811682527c0100000000000000000000000000000000000000000000000000000000900463ffffffff16918101829052901580610c2c575080517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16155b15610c7b576040517f06439c6b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610931565b6000816020015163ffffffff1642610c9391906119fe565b90507f000000000000000000000000000000000000000000000000000000000000000063ffffffff16811115610d40576040517fc65fdfca00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015263ffffffff7f000000000000000000000000000000000000000000000000000000000000000016602482015260448101829052606401610931565b505192915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610dfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610931565b565b60005b8251811015610ea857610e36838281518110610e1e57610e1e61190b565b602002602001015160046111b290919063ffffffff16565b15610e9857828181518110610e4d57610e4d61190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f34a02290b7920078c19f58e94b78c77eb9cc10195b20676e19bd3b82085893b860405160405180910390a25b610ea1816119a3565b9050610e00565b5060005b8151811015610f5457610ee2828281518110610eca57610eca61190b565b602002602001015160046111d490919063ffffffff16565b15610f4457818181518110610ef957610ef961190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fff7dbb85c77ca68ca1f894d6498570e3d5095cd19466f07ee8d222b337e4068c60405160405180910390a25b610f4d816119a3565b9050610eac565b505050565b60005b825181101561100457610f92838281518110610f7a57610f7a61190b565b602002602001015160066111b290919063ffffffff16565b15610ff457828181518110610fa957610fa961190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167fdf1b1bd32a69711488d71554706bb130b1fc63a5fa1a2cd85e8440f84065ba2360405160405180910390a25b610ffd816119a3565b9050610f5c565b5060005b8151811015610f545761103e8282815181106110265761102661190b565b602002602001015160066111d490919063ffffffff16565b156110a0578181815181106110555761105561190b565b602002602001015173ffffffffffffffffffffffffffffffffffffffff167f1795838dc8ab2ffc5f431a1729a6afa0b587f982f7b2be0b9d7187a1ef547f9160405160405180910390a25b6110a9816119a3565b9050611008565b60606000610d73836111f6565b3373ffffffffffffffffffffffffffffffffffffffff82160361113c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610931565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000610d738373ffffffffffffffffffffffffffffffffffffffff8416611252565b6000610d738373ffffffffffffffffffffffffffffffffffffffff84166112a1565b60608160000180548060200260200160405190810160405280929190818152602001828054801561124657602002820191906000526020600020905b815481526020019060010190808311611232575b50505050509050919050565b60008181526001830160205260408120546112995750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561088d565b50600061088d565b6000818152600183016020526040812054801561138a5760006112c56001836119fe565b85549091506000906112d9906001906119fe565b905081811461133e5760008660000182815481106112f9576112f961190b565b906000526020600020015490508087600001848154811061131c5761131c61190b565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061134f5761134f611a11565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061088d565b600091505061088d565b803573ffffffffffffffffffffffffffffffffffffffff811681146113b857600080fd5b919050565b6000806000606084860312156113d257600080fd5b6113db84611394565b9250602084013591506113f060408501611394565b90509250925092565b600060208083528351808285015260005b818110156114265785810183015185820160400152820161140a565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b60006020828403121561147757600080fd5b813567ffffffffffffffff81111561148e57600080fd5b820160408185031215610d7357600080fd5b600080602083850312156114b357600080fd5b823567ffffffffffffffff808211156114cb57600080fd5b818501915085601f8301126114df57600080fd5b8135818111156114ee57600080fd5b8660208260051b850101111561150357600080fd5b60209290920196919550909350505050565b602080825282518282018190526000919060409081850190868401855b828110156115835761157384835180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16825260209081015163ffffffff16910152565b9284019290850190600101611532565b5091979650505050505050565b6000602082840312156115a257600080fd5b610d7382611394565b803567ffffffffffffffff811681146113b857600080fd5b6000602082840312156115d557600080fd5b610d73826115ab565b81517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815260208083015163ffffffff16908201526040810161088d565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561166b5761166b611619565b60405290565b600082601f83011261168257600080fd5b8135602067ffffffffffffffff8083111561169f5761169f611619565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156116e2576116e2611619565b60405293845285810183019383810192508785111561170057600080fd5b83870191505b848210156117265761171782611394565b83529183019190830190611706565b979650505050505050565b6000806040838503121561174457600080fd5b823567ffffffffffffffff8082111561175c57600080fd5b61176886838701611671565b9350602085013591508082111561177e57600080fd5b5061178b85828601611671565b9150509250929050565b6020808252825182820181905260009190848201906040850190845b818110156117e357835173ffffffffffffffffffffffffffffffffffffffff16835292840192918401916001016117b1565b50909695505050505050565b6000806040838503121561180257600080fd5b61180b83611394565b9150611819602084016115ab565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808202811582820484141761088d5761088d611822565b60008261189e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126118d857600080fd5b83018035915067ffffffffffffffff8211156118f357600080fd5b6020019150600681901b3603821315610b7d57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b80357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146113b857600080fd5b60006040828403121561197857600080fd5b611980611648565b61198983611394565b81526119976020840161193a565b60208201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036119d4576119d4611822565b5060010190565b6000604082840312156119ed57600080fd5b6119f5611648565b611989836115ab565b8181038181111561088d5761088d611822565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var PriceRegistryABI = PriceRegistryMetaData.ABI diff --git a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go index 208a76ffd5..b2696011f3 100644 --- a/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go +++ b/core/gethwrappers/ccip/generated/usdc_token_pool/usdc_token_pool.go @@ -70,8 +70,8 @@ type USDCTokenPoolUSDCConfig struct { } var USDCTokenPoolMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageTransmitter\",\"type\":\"address\"}],\"internalType\":\"structUSDCTokenPool.USDCConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"localDomainIdentifier\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"NonExistentRamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermissionsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"RampAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageTransmitter\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.USDCConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"onRamps\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"offRamps\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"currentOffRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"currentOnRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageTransmitter\",\"type\":\"address\"}],\"internalType\":\"structUSDCTokenPool.USDCConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOnRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getUSDCInterfaceId\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"isOnRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"destinationReceiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageTransmitter\",\"type\":\"address\"}],\"internalType\":\"structUSDCTokenPool.USDCConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOffRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOnRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes4\",\"name\":\"interfaceId\",\"type\":\"bytes4\"}],\"name\":\"supportsInterface\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b50604051620041ff380380620041ff8339810160408190526200003591620008d5565b83838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000150565b5050506001600160a01b038316620000ed576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808416608052811660a052815115801560c0526200012857604080516000815260208101909152620001289083620001fb565b5050506200013c856200036c60201b60201c565b63ffffffff1660e0525062000a8892505050565b336001600160a01b03821603620001aa5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200021c576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002b1576000838281518110620002405762000240620009cb565b602090810291909101015190506200025a60028262000643565b156200029d576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50620002a981620009f7565b90506200021f565b5060005b815181101562000367576000828281518110620002d657620002d6620009cb565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000302575062000354565b6200030f60028262000663565b1562000352576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6200035f81620009f7565b9050620002b5565b505050565b805163ffffffff16156200039f5780516040516334697c6b60e11b815263ffffffff909116600482015260240162000086565b60408101516001600160a01b03161580620003c5575060208101516001600160a01b0316155b15620003e4576040516306b7c75960e31b815260040160405180910390fd5b600081602001516001600160a01b0316639cdbb1816040518163ffffffff1660e01b81526004016020604051808303816000875af11580156200042b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000451919062000a13565b905063ffffffff81161562000482576040516316ba39c560e31b815263ffffffff8216600482015260240162000086565b600a5464010000000090046001600160a01b0316156200052257608051600a5460405163095ea7b360e01b81526001600160a01b03640100000000909204821660048201526000602482015291169063095ea7b3906044016020604051808303816000875af1158015620004fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000520919062000a31565b505b608051602083015160405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af11580156200057b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005a1919062000a31565b508151600a80546020808601805163ffffffff9095166001600160c01b031990931683176401000000006001600160a01b03968716021790935560408087018051600b80546001600160a01b031916918816919091179055815193845293518516918301919091529151909216908201527f33a7d35707e0c8e46d6fa8dd98b73765c14247a559106927070b1cfd2933f4039060600160405180910390a15050565b60006200065a836001600160a01b0384166200067a565b90505b92915050565b60006200065a836001600160a01b0384166200077e565b6000818152600183016020526040812054801562000773576000620006a160018362000a5c565b8554909150600090620006b79060019062000a5c565b905081811462000723576000866000018281548110620006db57620006db620009cb565b9060005260206000200154905080876000018481548110620007015762000701620009cb565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000737576200073762000a72565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200065d565b60009150506200065d565b6000818152600183016020526040812054620007c7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200065d565b5060006200065d565b634e487b7160e01b600052604160045260246000fd5b805163ffffffff81168114620007fb57600080fd5b919050565b6001600160a01b03811681146200081657600080fd5b50565b8051620007fb8162000800565b600082601f8301126200083857600080fd5b815160206001600160401b0380831115620008575762000857620007d0565b8260051b604051601f19603f830116810181811084821117156200087f576200087f620007d0565b6040529384528581018301938381019250878511156200089e57600080fd5b83870191505b84821015620008ca578151620008ba8162000800565b83529183019190830190620008a4565b979650505050505050565b600080600080600085870360e0811215620008ef57600080fd5b6060811215620008fe57600080fd5b50604051606081016001600160401b038082118383101715620009255762000925620007d0565b816040526200093489620007e6565b835260208901519150620009488262000800565b81602084015260408901519150620009608262000800565b8160408401528297506200097760608a0162000819565b965060808901519250808311156200098e57600080fd5b50506200099e8882890162000826565b935050620009af60a0870162000819565b9150620009bf60c08701620007e6565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162000a0c5762000a0c620009e1565b5060010190565b60006020828403121562000a2657600080fd5b6200065a82620007e6565b60006020828403121562000a4457600080fd5b8151801515811462000a5557600080fd5b9392505050565b818103818111156200065d576200065d620009e1565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e0516136f762000b08600039600081816102a501528181610fcd01528181611c8d0152611ceb0152600081816105ae01528181610d4f01526117710152600061026901526000818161020f01528181610ee8015281816115490152818161162801528181611bb10152611da901526136f76000f3fe608060405234801561001057600080fd5b50600436106101b85760003560e01c80638627fad6116100f9578063b3a3fb4111610097578063d612b94511610071578063d612b945146104fb578063dfadfa351461050e578063e0351e13146105ac578063f2fde38b146105d257600080fd5b8063b3a3fb4114610425578063c3f909d414610438578063c49907b5146104e857600080fd5b806396875445116100d357806396875445146103ed5780639fdf13ff1461040d578063a40e69c714610415578063a7cd63b71461041d57600080fd5b80638627fad6146103a757806387381314146103ba5780638da5cb5b146103cf57600080fd5b806354c8a4f3116101665780636f32b872116101405780636f32b8721461030a5780637448b3c71461031d5780637787e7ab1461033057806379ba50971461039f57600080fd5b806354c8a4f31461028d5780636b716b0d146102a05780636d108139146102dc57600080fd5b806321df0da71161019757806321df0da71461020d578063263a890a146102545780635246492f1461026757600080fd5b806241d3c1146101bd57806301ffc9a7146101d25780631d7a74a0146101fa575b600080fd5b6101d06101cb366004612a15565b6105e5565b005b6101e56101e0366004612a8a565b61078c565b60405190151581526020015b60405180910390f35b6101e5610208366004612af5565b6107e8565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f1565b6101d0610262366004612bec565b6107f5565b7f000000000000000000000000000000000000000000000000000000000000000061022f565b6101d061029b366004612c88565b610809565b6102c77f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101f1565b6040517fd6aca1be0000000000000000000000000000000000000000000000000000000081526020016101f1565b6101e5610318366004612af5565b610884565b6101d061032b366004612d73565b610891565b61034361033e366004612af5565b610950565b6040516101f1919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6101d0610a2e565b6101d06103b5366004612e59565b610b2b565b6103c2610cfa565b6040516101f19190612eec565b60005473ffffffffffffffffffffffffffffffffffffffff1661022f565b6104006103fb366004612f88565b610d0b565b6040516101f19190613095565b6102c7600081565b6103c2611025565b6103c2611031565b610343610433366004612af5565b61103d565b6104a260408051606081018252600080825260208201819052918101919091525060408051606081018252600a5463ffffffff8116825273ffffffffffffffffffffffffffffffffffffffff64010000000090910481166020830152600b54169181019190915290565b60408051825163ffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101f1565b6101d06104f63660046130ed565b61111b565b6101d0610509366004612d73565b61112f565b61058261051c36600461314d565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600c82529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff1690820152918101511515908201526060016101f1565b7f00000000000000000000000000000000000000000000000000000000000000006101e5565b6101d06105e0366004612af5565b6111ee565b6105ed6111ff565b60005b8181101561074e57600083838381811061060c5761060c61316a565b9050608002018036038101906106229190613199565b8051909150158061063f5750604081015167ffffffffffffffff16155b156106ae57604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600c90925293902091518255516001909101805493511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909416919092161791909117905561074781613244565b90506105f0565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee56828260405161078092919061327c565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd6aca1be0000000000000000000000000000000000000000000000000000000014806107e257506107e282611282565b92915050565b60006107e260078361131a565b6107fd6111ff565b6108068161134c565b50565b6108116111ff565b61087e8484808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525061176f92505050565b50505050565b60006107e260048361131a565b6108996111ff565b6108a282610884565b6108f0576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016106a5565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260066020526040902061091f908261193a565b7f578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed68282604051610780929190613305565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260066020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526107e290611ae9565b60015473ffffffffffffffffffffffffffffffffffffffff163314610aaf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106a5565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b34336107e8565b610b6a576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b7383611b9b565b60008082806020019051810190610b8a91906133aa565b91509150600082806020019051810190610ba4919061340e565b9050600082806020019051810190610bbc919061344f565b9050610bcc816000015183611bd5565b600b54815160208301516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909316926357ecfd2892610c299290916004016134e0565b6020604051808303816000875af1158015610c48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6c9190613505565b610ca2576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405187815273ffffffffffffffffffffffffffffffffffffffff89169033907f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f09060200160405180910390a3505050505050505050565b6060610d066004611d86565b905090565b6060610d1633610884565b610d4c576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b877f00000000000000000000000000000000000000000000000000000000000000008015610d825750610d8060028261131a565b155b15610dd1576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016106a5565b67ffffffffffffffff85166000908152600c602090815260409182902082516060810184528154815260019091015463ffffffff81169282019290925264010000000090910460ff16151591810182905290610e65576040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff871660048201526024016106a5565b610e6e87611d93565b6000610e7d6020828b8d613522565b610e869161354c565b600a54602084015184516040517ff856ddb6000000000000000000000000000000000000000000000000000000008152600481018d905263ffffffff90921660248301526044820184905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529293506000926401000000009092049091169063f856ddb69060a4016020604051808303816000875af1158015610f51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f759190613588565b6040518a815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260408051808201825267ffffffffffffffff9290921680835263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602094850190815283519485019290925290511682820152805180830382018152606090920190529b9a5050505050505050505050565b6060610d066007611d86565b6060610d066002611d86565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260096020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff1615159482019490945260019091015480841660608301529190910490911660808201526107e290611ae9565b6111236111ff565b61087e84848484611dcd565b6111376111ff565b611140826107e8565b61118e576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016106a5565b73ffffffffffffffffffffffffffffffffffffffff821660009081526009602052604090206111bd908261193a565b7fb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f8282604051610780929190613305565b6111f66111ff565b6108068161237d565b60005473ffffffffffffffffffffffffffffffffffffffff163314611280576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106a5565b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa3340000000000000000000000000000000000000000000000000000000014806107e257507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b805163ffffffff16156113965780516040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff90911660048201526024016106a5565b604081015173ffffffffffffffffffffffffffffffffffffffff1615806113d55750602081015173ffffffffffffffffffffffffffffffffffffffff16155b1561140c576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816020015173ffffffffffffffffffffffffffffffffffffffff16639cdbb1816040518163ffffffff1660e01b81526004016020604051808303816000875af115801561145f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148391906135a5565b905063ffffffff8116156114cb576040517fb5d1ce2800000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016106a5565b600a54640100000000900473ffffffffffffffffffffffffffffffffffffffff16156115b857600a546040517f095ea7b300000000000000000000000000000000000000000000000000000000815264010000000090910473ffffffffffffffffffffffffffffffffffffffff9081166004830152600060248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303816000875af1158015611592573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115b69190613505565b505b60208201516040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248201527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af1158015611673573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116979190613505565b508151600a80546020808601805163ffffffff9095167fffffffffffffffff000000000000000000000000000000000000000000000000909316831764010000000073ffffffffffffffffffffffffffffffffffffffff968716021790935560408087018051600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918816919091179055815193845293518516918301919091529151909216908201527f33a7d35707e0c8e46d6fa8dd98b73765c14247a559106927070b1cfd2933f40390606001610780565b7f00000000000000000000000000000000000000000000000000000000000000006117c6576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118645760008382815181106117e6576117e661316a565b6020026020010151905061180481600261247290919063ffffffff16565b156118535760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b5061185d81613244565b90506117c9565b5060005b81518110156119355760008282815181106118855761188561316a565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036118c95750611925565b6118d4600282612494565b156119235760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b61192e81613244565b9050611868565b505050565b815460009061196390700100000000000000000000000000000000900463ffffffff16426135c2565b90508015611a0557600183015483546119ab916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166124b6565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354611a2b916fffffffffffffffffffffffffffffffff90811691166124de565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611adc9084906135d5565b60405180910390a1505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611b7782606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611b5b91906135c2565b85608001516fffffffffffffffffffffffffffffffff166124b6565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b33600090815260096020526040902061080690827f00000000000000000000000000000000000000000000000000000000000000006124f4565b600482015163ffffffff811615611c20576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016106a5565b6008830151600c8401516014850151602085015163ffffffff808516911614611c8b5760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff918216600482015290841660248201526044016106a5565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611d20576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152831660248201526044016106a5565b845167ffffffffffffffff828116911614611d7e5784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff918216600482015290821660248201526044016106a5565b505050505050565b6060600061134583612877565b33600090815260066020526040902061080690827f00000000000000000000000000000000000000000000000000000000000000006124f4565b611dd56111ff565b60005b838110156120f2576000858583818110611df457611df461316a565b905060a00201803603810190611e0a9190613611565b9050806020015115611fe2578051611e2490600490612494565b15611f95576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526006909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac92611f889291613305565b60405180910390a16120e1565b80516040517fd3eb6bc500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016106a5565b8051611ff090600490612472565b1561209457805173ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517f7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b529491611f889173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b80516040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016106a5565b506120eb81613244565b9050611dd8565b5060005b818110156123765760008383838181106121125761211261316a565b905060a002018036038101906121289190613611565b90508060200151156122b357805161214290600790612494565b15611f95576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526009909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d88926122a69291613305565b60405180910390a1612365565b80516122c190600790612472565b1561209457805173ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517fcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c916122a69173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b5061236f81613244565b90506120f6565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff8216036123fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106a5565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60006113458373ffffffffffffffffffffffffffffffffffffffff84166128d3565b60006113458373ffffffffffffffffffffffffffffffffffffffff84166129c6565b60006124d5856124c68486613656565b6124d0908761366d565b6124de565b95945050505050565b60008183106124ed5781611345565b5090919050565b825474010000000000000000000000000000000000000000900460ff16158061251b575081155b1561252557505050565b825460018401546fffffffffffffffffffffffffffffffff8083169291169060009061256b90700100000000000000000000000000000000900463ffffffff16426135c2565b9050801561262b57818311156125ad576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018601546125e79083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166124b6565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156126e25773ffffffffffffffffffffffffffffffffffffffff841661268a576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106a5565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016106a5565b848310156127f55760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061272690826135c2565b612730878a6135c2565b61273a919061366d565b6127449190613680565b905073ffffffffffffffffffffffffffffffffffffffff861661279d576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106a5565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016106a5565b6127ff85846135c2565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b6060816000018054806020026020016040519081016040528092919081815260200182805480156128c757602002820191906000526020600020905b8154815260200190600101908083116128b3575b50505050509050919050565b600081815260018301602052604081205480156129bc5760006128f76001836135c2565b855490915060009061290b906001906135c2565b905081811461297057600086600001828154811061292b5761292b61316a565b906000526020600020015490508087600001848154811061294e5761294e61316a565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612981576129816136bb565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506107e2565b60009150506107e2565b6000818152600183016020526040812054612a0d575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556107e2565b5060006107e2565b60008060208385031215612a2857600080fd5b823567ffffffffffffffff80821115612a4057600080fd5b818501915085601f830112612a5457600080fd5b813581811115612a6357600080fd5b8660208260071b8501011115612a7857600080fd5b60209290920196919550909350505050565b600060208284031215612a9c57600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461134557600080fd5b803573ffffffffffffffffffffffffffffffffffffffff81168114612af057600080fd5b919050565b600060208284031215612b0757600080fd5b61134582612acc565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612b6257612b62612b10565b60405290565b6040805190810167ffffffffffffffff81118282101715612b6257612b62612b10565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612bd257612bd2612b10565b604052919050565b63ffffffff8116811461080657600080fd5b600060608284031215612bfe57600080fd5b612c06612b3f565b8235612c1181612bda565b8152612c1f60208401612acc565b6020820152612c3060408401612acc565b60408201529392505050565b60008083601f840112612c4e57600080fd5b50813567ffffffffffffffff811115612c6657600080fd5b6020830191508360208260051b8501011115612c8157600080fd5b9250929050565b60008060008060408587031215612c9e57600080fd5b843567ffffffffffffffff80821115612cb657600080fd5b612cc288838901612c3c565b90965094506020870135915080821115612cdb57600080fd5b50612ce887828801612c3c565b95989497509550505050565b801515811461080657600080fd5b80356fffffffffffffffffffffffffffffffff81168114612af057600080fd5b600060608284031215612d3457600080fd5b612d3c612b3f565b90508135612d4981612cf4565b8152612d5760208301612d02565b6020820152612d6860408301612d02565b604082015292915050565b60008060808385031215612d8657600080fd5b612d8f83612acc565b9150612d9e8460208501612d22565b90509250929050565b600067ffffffffffffffff821115612dc157612dc1612b10565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112612dfe57600080fd5b8135612e11612e0c82612da7565b612b8b565b818152846020838601011115612e2657600080fd5b816020850160208301376000918101602001919091529392505050565b67ffffffffffffffff8116811461080657600080fd5b600080600080600060a08688031215612e7157600080fd5b853567ffffffffffffffff80821115612e8957600080fd5b612e9589838a01612ded565b9650612ea360208901612acc565b95506040880135945060608801359150612ebc82612e43565b90925060808701359080821115612ed257600080fd5b50612edf88828901612ded565b9150509295509295909350565b6020808252825182820181905260009190848201906040850190845b81811015612f3a57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612f08565b50909695505050505050565b60008083601f840112612f5857600080fd5b50813567ffffffffffffffff811115612f7057600080fd5b602083019150836020828501011115612c8157600080fd5b600080600080600080600060a0888a031215612fa357600080fd5b612fac88612acc565b9650602088013567ffffffffffffffff80821115612fc957600080fd5b612fd58b838c01612f46565b909850965060408a0135955060608a01359150612ff182612e43565b9093506080890135908082111561300757600080fd5b506130148a828b01612f46565b989b979a50959850939692959293505050565b60005b8381101561304257818101518382015260200161302a565b50506000910152565b60008151808452613063816020860160208601613027565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000611345602083018461304b565b60008083601f8401126130ba57600080fd5b50813567ffffffffffffffff8111156130d257600080fd5b60208301915083602060a083028501011115612c8157600080fd5b6000806000806040858703121561310357600080fd5b843567ffffffffffffffff8082111561311b57600080fd5b613127888389016130a8565b9096509450602087013591508082111561314057600080fd5b50612ce8878288016130a8565b60006020828403121561315f57600080fd5b813561134581612e43565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000608082840312156131ab57600080fd5b6040516080810181811067ffffffffffffffff821117156131ce576131ce612b10565b6040528235815260208301356131e381612bda565b602082015260408301356131f681612e43565b6040820152606083013561320981612cf4565b60608201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361327557613275613215565b5060010190565b6020808252818101839052600090604080840186845b878110156132f85781358352848201356132ab81612bda565b63ffffffff1683860152818401356132c281612e43565b67ffffffffffffffff16838501526060828101356132df81612cf4565b1515908401526080928301929190910190600101613292565b5090979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff831681526080810161134560208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600082601f83011261336e57600080fd5b815161337c612e0c82612da7565b81815284602083860101111561339157600080fd5b6133a2826020830160208701613027565b949350505050565b600080604083850312156133bd57600080fd5b825167ffffffffffffffff808211156133d557600080fd5b6133e18683870161335d565b935060208501519150808211156133f757600080fd5b506134048582860161335d565b9150509250929050565b60006040828403121561342057600080fd5b613428612b68565b825161343381612e43565b8152602083015161344381612bda565b60208201529392505050565b60006020828403121561346157600080fd5b815167ffffffffffffffff8082111561347957600080fd5b908301906040828603121561348d57600080fd5b613495612b68565b8251828111156134a457600080fd5b6134b08782860161335d565b8252506020830151828111156134c557600080fd5b6134d18782860161335d565b60208301525095945050505050565b6040815260006134f3604083018561304b565b82810360208401526124d5818561304b565b60006020828403121561351757600080fd5b815161134581612cf4565b6000808585111561353257600080fd5b8386111561353f57600080fd5b5050820193919092039150565b803560208310156107e2577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b60006020828403121561359a57600080fd5b815161134581612e43565b6000602082840312156135b757600080fd5b815161134581612bda565b818103818111156107e2576107e2613215565b606081016107e282848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060a0828403121561362357600080fd5b61362b612b3f565b61363483612acc565b8152602083013561364481612cf4565b6020820152612c308460408501612d22565b80820281158282048414176107e2576107e2613215565b808201808211156107e2576107e2613215565b6000826136b6577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageTransmitter\",\"type\":\"address\"}],\"internalType\":\"structUSDCTokenPool.USDCConfig\",\"name\":\"config\",\"type\":\"tuple\"},{\"internalType\":\"contractIBurnMintERC20\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"allowlist\",\"type\":\"address[]\"},{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"localDomainIdentifier\",\"type\":\"uint32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"}],\"name\":\"AggregateValueMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"}],\"name\":\"AggregateValueRateLimitReached\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AllowListNotEnabled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BadARMSignal\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BucketOverfilled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidConfig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidDestinationDomain\",\"type\":\"error\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate\",\"name\":\"domain\",\"type\":\"tuple\"}],\"name\":\"InvalidDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidMessageVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"expected\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"got\",\"type\":\"uint64\"}],\"name\":\"InvalidNonce\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"expected\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"got\",\"type\":\"uint32\"}],\"name\":\"InvalidSourceDomain\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"}],\"name\":\"InvalidTokenMessengerVersion\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"NonExistentRamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PermissionsError\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"}],\"name\":\"RampAlreadyExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"SenderNotAllowed\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"capacity\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requested\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenMaxCapacityExceeded\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"minWaitInSeconds\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"available\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"tokenAddress\",\"type\":\"address\"}],\"name\":\"TokenRateLimitReached\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"domain\",\"type\":\"uint64\"}],\"name\":\"UnknownDomain\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnlockingUSDCFailed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListAdd\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"AllowListRemove\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Burned\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageTransmitter\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.USDCConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"indexed\":false,\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"name\":\"DomainsSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Locked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Minted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OffRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"OffRampRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"indexed\":false,\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"name\":\"OnRampConfigured\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"OnRampRemoved\",\"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\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Released\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUPPORTED_USDC_VERSION\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"removes\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"adds\",\"type\":\"address[]\"}],\"name\":\"applyAllowListUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"onRamps\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"ramp\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"allowed\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"rateLimiterConfig\",\"type\":\"tuple\"}],\"internalType\":\"structTokenPool.RampUpdate[]\",\"name\":\"offRamps\",\"type\":\"tuple[]\"}],\"name\":\"applyRampUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"currentOffRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"currentOnRampRateLimiterState\",\"outputs\":[{\"components\":[{\"internalType\":\"uint128\",\"name\":\"tokens\",\"type\":\"uint128\"},{\"internalType\":\"uint32\",\"name\":\"lastUpdated\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.TokenBucket\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowList\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllowListEnabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getArmProxy\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"armProxy\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageTransmitter\",\"type\":\"address\"}],\"internalType\":\"structUSDCTokenPool.USDCConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getDomain\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.Domain\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOffRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOnRamps\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getToken\",\"outputs\":[{\"internalType\":\"contractIERC20\",\"name\":\"token\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getUSDCInterfaceId\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"i_localDomainIdentifier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"}],\"name\":\"isOffRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"}],\"name\":\"isOnRamp\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"originalSender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"destinationReceiver\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"name\":\"lockOrBurn\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"extraData\",\"type\":\"bytes\"}],\"name\":\"releaseOrMint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"version\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"tokenMessenger\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"messageTransmitter\",\"type\":\"address\"}],\"internalType\":\"structUSDCTokenPool.USDCConfig\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"allowedCaller\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"domainIdentifier\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bool\",\"name\":\"enabled\",\"type\":\"bool\"}],\"internalType\":\"structUSDCTokenPool.DomainUpdate[]\",\"name\":\"domains\",\"type\":\"tuple[]\"}],\"name\":\"setDomains\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"offRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOffRampRateLimiterConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"onRamp\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"bool\",\"name\":\"isEnabled\",\"type\":\"bool\"},{\"internalType\":\"uint128\",\"name\":\"capacity\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"rate\",\"type\":\"uint128\"}],\"internalType\":\"structRateLimiter.Config\",\"name\":\"config\",\"type\":\"tuple\"}],\"name\":\"setOnRampRateLimiterConfig\",\"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\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004246380380620042468339810160408190526200003591620008d5565b83838333806000816200008f5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000c257620000c28162000150565b5050506001600160a01b038316620000ed576040516342bcdf7f60e11b815260040160405180910390fd5b6001600160a01b03808416608052811660a052815115801560c0526200012857604080516000815260208101909152620001289083620001fb565b5050506200013c856200036c60201b60201c565b63ffffffff1660e0525062000a8892505050565b336001600160a01b03821603620001aa5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000086565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60c0516200021c576040516335f4a7b360e01b815260040160405180910390fd5b60005b8251811015620002b1576000838281518110620002405762000240620009cb565b602090810291909101015190506200025a60028262000643565b156200029d576040516001600160a01b03821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b50620002a981620009f7565b90506200021f565b5060005b815181101562000367576000828281518110620002d657620002d6620009cb565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000302575062000354565b6200030f60028262000663565b1562000352576040516001600160a01b03821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6200035f81620009f7565b9050620002b5565b505050565b805163ffffffff16156200039f5780516040516334697c6b60e11b815263ffffffff909116600482015260240162000086565b60408101516001600160a01b03161580620003c5575060208101516001600160a01b0316155b15620003e4576040516306b7c75960e31b815260040160405180910390fd5b600081602001516001600160a01b0316639cdbb1816040518163ffffffff1660e01b81526004016020604051808303816000875af11580156200042b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000451919062000a13565b905063ffffffff81161562000482576040516316ba39c560e31b815263ffffffff8216600482015260240162000086565b600a5464010000000090046001600160a01b0316156200052257608051600a5460405163095ea7b360e01b81526001600160a01b03640100000000909204821660048201526000602482015291169063095ea7b3906044016020604051808303816000875af1158015620004fa573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000520919062000a31565b505b608051602083015160405163095ea7b360e01b81526001600160a01b039182166004820152600019602482015291169063095ea7b3906044016020604051808303816000875af11580156200057b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620005a1919062000a31565b508151600a80546020808601805163ffffffff9095166001600160c01b031990931683176401000000006001600160a01b03968716021790935560408087018051600b80546001600160a01b031916918816919091179055815193845293518516918301919091529151909216908201527f33a7d35707e0c8e46d6fa8dd98b73765c14247a559106927070b1cfd2933f4039060600160405180910390a15050565b60006200065a836001600160a01b0384166200067a565b90505b92915050565b60006200065a836001600160a01b0384166200077e565b6000818152600183016020526040812054801562000773576000620006a160018362000a5c565b8554909150600090620006b79060019062000a5c565b905081811462000723576000866000018281548110620006db57620006db620009cb565b9060005260206000200154905080876000018481548110620007015762000701620009cb565b6000918252602080832090910192909255918252600188019052604090208390555b855486908062000737576200073762000a72565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200065d565b60009150506200065d565b6000818152600183016020526040812054620007c7575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200065d565b5060006200065d565b634e487b7160e01b600052604160045260246000fd5b805163ffffffff81168114620007fb57600080fd5b919050565b6001600160a01b03811681146200081657600080fd5b50565b8051620007fb8162000800565b600082601f8301126200083857600080fd5b815160206001600160401b0380831115620008575762000857620007d0565b8260051b604051601f19603f830116810181811084821117156200087f576200087f620007d0565b6040529384528581018301938381019250878511156200089e57600080fd5b83870191505b84821015620008ca578151620008ba8162000800565b83529183019190830190620008a4565b979650505050505050565b600080600080600085870360e0811215620008ef57600080fd5b6060811215620008fe57600080fd5b50604051606081016001600160401b038082118383101715620009255762000925620007d0565b816040526200093489620007e6565b835260208901519150620009488262000800565b81602084015260408901519150620009608262000800565b8160408401528297506200097760608a0162000819565b965060808901519250808311156200098e57600080fd5b50506200099e8882890162000826565b935050620009af60a0870162000819565b9150620009bf60c08701620007e6565b90509295509295909350565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162000a0c5762000a0c620009e1565b5060010190565b60006020828403121562000a2657600080fd5b6200065a82620007e6565b60006020828403121562000a4457600080fd5b8151801515811462000a5557600080fd5b9392505050565b818103818111156200065d576200065d620009e1565b634e487b7160e01b600052603160045260246000fd5b60805160a05160c05160e05161373e62000b08600039600081816102f90152818161101401528181611cd40152611d320152600081816105f501528181610d9601526117b8015260006102bd01526000818161026301528181610f2f015281816115900152818161166f01528181611bf80152611df0015261373e6000f3fe608060405234801561001057600080fd5b50600436106101c35760003560e01c80638627fad6116100f9578063b3a3fb4111610097578063d612b94511610071578063d612b94514610542578063dfadfa3514610555578063e0351e13146105f3578063f2fde38b1461061957600080fd5b8063b3a3fb411461046c578063c3f909d41461047f578063c49907b51461052f57600080fd5b806396875445116100d357806396875445146104415780639fdf13ff14610454578063a40e69c71461045c578063a7cd63b71461046457600080fd5b80638627fad6146103fb578063873813141461040e5780638da5cb5b1461042357600080fd5b806354c8a4f3116101665780636f32b872116101405780636f32b8721461035e5780637448b3c7146103715780637787e7ab1461038457806379ba5097146103f357600080fd5b806354c8a4f3146102e15780636b716b0d146102f45780636d1081391461033057600080fd5b80631d7a74a0116101a25780631d7a74a01461024e57806321df0da714610261578063263a890a146102a85780635246492f146102bb57600080fd5b806241d3c1146101c857806301ffc9a7146101dd578063181f5a7714610205575b600080fd5b6101db6101d6366004612a5c565b61062c565b005b6101f06101eb366004612ad1565b6107d3565b60405190151581526020015b60405180910390f35b6102416040518060400160405280601381526020017f55534443546f6b656e506f6f6c20312e322e300000000000000000000000000081525081565b6040516101fc9190612b81565b6101f061025c366004612bbd565b61082f565b7f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101fc565b6101db6102b6366004612cb4565b61083c565b7f0000000000000000000000000000000000000000000000000000000000000000610283565b6101db6102ef366004612d50565b610850565b61031b7f000000000000000000000000000000000000000000000000000000000000000081565b60405163ffffffff90911681526020016101fc565b6040517fd6aca1be0000000000000000000000000000000000000000000000000000000081526020016101fc565b6101f061036c366004612bbd565b6108cb565b6101db61037f366004612e3b565b6108d8565b610397610392366004612bbd565b610997565b6040516101fc919081516fffffffffffffffffffffffffffffffff908116825260208084015163ffffffff1690830152604080840151151590830152606080840151821690830152608092830151169181019190915260a00190565b6101db610a75565b6101db610409366004612f21565b610b72565b610416610d41565b6040516101fc9190612fb4565b60005473ffffffffffffffffffffffffffffffffffffffff16610283565b61024161044f366004613050565b610d52565b61031b600081565b61041661106c565b610416611078565b61039761047a366004612bbd565b611084565b6104e960408051606081018252600080825260208201819052918101919091525060408051606081018252600a5463ffffffff8116825273ffffffffffffffffffffffffffffffffffffffff64010000000090910481166020830152600b54169181019190915290565b60408051825163ffffffff16815260208084015173ffffffffffffffffffffffffffffffffffffffff9081169183019190915292820151909216908201526060016101fc565b6101db61053d366004613134565b611162565b6101db610550366004612e3b565b611176565b6105c9610563366004613194565b60408051606080820183526000808352602080840182905292840181905267ffffffffffffffff949094168452600c82529282902082519384018352805484526001015463ffffffff811691840191909152640100000000900460ff1615159082015290565b604080518251815260208084015163ffffffff1690820152918101511515908201526060016101fc565b7f00000000000000000000000000000000000000000000000000000000000000006101f0565b6101db610627366004612bbd565b611235565b610634611246565b60005b81811015610795576000838383818110610653576106536131b1565b90506080020180360381019061066991906131e0565b805190915015806106865750604081015167ffffffffffffffff16155b156106f557604080517fa087bd2900000000000000000000000000000000000000000000000000000000815282516004820152602083015163ffffffff1660248201529082015167ffffffffffffffff1660448201526060820151151560648201526084015b60405180910390fd5b60408051606080820183528351825260208085015163ffffffff9081168285019081529286015115158486019081529585015167ffffffffffffffff166000908152600c90925293902091518255516001909101805493511515640100000000027fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000909416919092161791909117905561078e8161328b565b9050610637565b507f1889010d2535a0ab1643678d1da87fbbe8b87b2f585b47ddb72ec622aef9ee5682826040516107c79291906132c3565b60405180910390a15050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd6aca1be0000000000000000000000000000000000000000000000000000000014806108295750610829826112c9565b92915050565b6000610829600783611361565b610844611246565b61084d81611393565b50565b610858611246565b6108c5848480806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250506040805160208088028281018201909352878252909350879250869182918501908490808284376000920191909152506117b692505050565b50505050565b6000610829600483611361565b6108e0611246565b6108e9826108cb565b610937576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016106ec565b73ffffffffffffffffffffffffffffffffffffffff821660009081526006602052604090206109669082611981565b7f578db78e348076074dbff64a94073a83e9a65aa6766b8c75fdc89282b0e30ed682826040516107c792919061334c565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260066020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261082990611b30565b60015473ffffffffffffffffffffffffffffffffffffffff163314610af6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016106ec565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610b7b3361082f565b610bb1576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610bba83611be2565b60008082806020019051810190610bd191906133f1565b91509150600082806020019051810190610beb9190613455565b9050600082806020019051810190610c039190613496565b9050610c13816000015183611c1c565b600b54815160208301516040517f57ecfd2800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909316926357ecfd2892610c70929091600401613527565b6020604051808303816000875af1158015610c8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb3919061354c565b610ce9576040517fbf969f2200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405187815273ffffffffffffffffffffffffffffffffffffffff89169033907f9d228d69b5fdb8d273a2336f8fb8612d039631024ea9bf09c424a9503aa078f09060200160405180910390a3505050505050505050565b6060610d4d6004611dcd565b905090565b6060610d5d336108cb565b610d93576040517f5307f5ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b877f00000000000000000000000000000000000000000000000000000000000000008015610dc95750610dc7600282611361565b155b15610e18576040517fd0d2597600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024016106ec565b67ffffffffffffffff85166000908152600c602090815260409182902082516060810184528154815260019091015463ffffffff81169282019290925264010000000090910460ff16151591810182905290610eac576040517fd201c48a00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff871660048201526024016106ec565b610eb587611dda565b6000610ec46020828b8d613569565b610ecd91613593565b600a54602084015184516040517ff856ddb6000000000000000000000000000000000000000000000000000000008152600481018d905263ffffffff90921660248301526044820184905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116606484015260848301919091529293506000926401000000009092049091169063f856ddb69060a4016020604051808303816000875af1158015610f98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbc91906135cf565b6040518a815290915033907f696de425f79f4a40bc6d2122ca50507f0efbeabbff86a84871b7196ab8ea8df79060200160405180910390a260408051808201825267ffffffffffffffff9290921680835263ffffffff7f00000000000000000000000000000000000000000000000000000000000000008116602094850190815283519485019290925290511682820152805180830382018152606090920190529b9a5050505050505050505050565b6060610d4d6007611dcd565b6060610d4d6002611dcd565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915273ffffffffffffffffffffffffffffffffffffffff8216600090815260096020908152604091829020825160a08101845281546fffffffffffffffffffffffffffffffff808216835270010000000000000000000000000000000080830463ffffffff16958401959095527401000000000000000000000000000000000000000090910460ff16151594820194909452600190910154808416606083015291909104909116608082015261082990611b30565b61116a611246565b6108c584848484611e14565b61117e611246565b6111878261082f565b6111d5576040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff831660048201526024016106ec565b73ffffffffffffffffffffffffffffffffffffffff821660009081526009602052604090206112049082611981565b7fb3ba339cfbb8ef80d7a29ce5493051cb90e64fcfa85d7124efc1adfa4c68399f82826040516107c792919061334c565b61123d611246565b61084d816123c4565b60005473ffffffffffffffffffffffffffffffffffffffff1633146112c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016106ec565b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f317fa33400000000000000000000000000000000000000000000000000000000148061082957507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a7000000000000000000000000000000000000000000000000000000001492915050565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260018301602052604081205415155b9392505050565b805163ffffffff16156113dd5780516040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff90911660048201526024016106ec565b604081015173ffffffffffffffffffffffffffffffffffffffff16158061141c5750602081015173ffffffffffffffffffffffffffffffffffffffff16155b15611453576040517f35be3ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000816020015173ffffffffffffffffffffffffffffffffffffffff16639cdbb1816040518163ffffffff1660e01b81526004016020604051808303816000875af11580156114a6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ca91906135ec565b905063ffffffff811615611512576040517fb5d1ce2800000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016106ec565b600a54640100000000900473ffffffffffffffffffffffffffffffffffffffff16156115ff57600a546040517f095ea7b300000000000000000000000000000000000000000000000000000000815264010000000090910473ffffffffffffffffffffffffffffffffffffffff9081166004830152600060248301527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303816000875af11580156115d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fd919061354c565b505b60208201516040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60248201527f00000000000000000000000000000000000000000000000000000000000000009091169063095ea7b3906044016020604051808303816000875af11580156116ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116de919061354c565b508151600a80546020808601805163ffffffff9095167fffffffffffffffff000000000000000000000000000000000000000000000000909316831764010000000073ffffffffffffffffffffffffffffffffffffffff968716021790935560408087018051600b80547fffffffffffffffffffffffff000000000000000000000000000000000000000016918816919091179055815193845293518516918301919091529151909216908201527f33a7d35707e0c8e46d6fa8dd98b73765c14247a559106927070b1cfd2933f403906060016107c7565b7f000000000000000000000000000000000000000000000000000000000000000061180d576040517f35f4a7b300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b82518110156118ab57600083828151811061182d5761182d6131b1565b6020026020010151905061184b8160026124b990919063ffffffff16565b1561189a5760405173ffffffffffffffffffffffffffffffffffffffff821681527f800671136ab6cfee9fbe5ed1fb7ca417811aca3cf864800d127b927adedf75669060200160405180910390a15b506118a48161328b565b9050611810565b5060005b815181101561197c5760008282815181106118cc576118cc6131b1565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611910575061196c565b61191b6002826124db565b1561196a5760405173ffffffffffffffffffffffffffffffffffffffff821681527f2640d4d76caf8bf478aabfa982fa4e1c4eb71a37f93cd15e80dbc657911546d89060200160405180910390a15b505b6119758161328b565b90506118af565b505050565b81546000906119aa90700100000000000000000000000000000000900463ffffffff1642613609565b90508015611a4c57600183015483546119f2916fffffffffffffffffffffffffffffffff808216928116918591700100000000000000000000000000000000909104166124fd565b83546fffffffffffffffffffffffffffffffff919091167fffffffffffffffffffffffff0000000000000000000000000000000000000000909116177001000000000000000000000000000000004263ffffffff16021783555b60208201518354611a72916fffffffffffffffffffffffffffffffff9081169116612525565b83548351151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffff000000000000000000000000000000009091166fffffffffffffffffffffffffffffffff92831617178455602083015160408085015183167001000000000000000000000000000000000291909216176001850155517f9ea3374b67bf275e6bb9c8ae68f9cae023e1c528b4b27e092f0bb209d3531c1990611b2390849061361c565b60405180910390a1505050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611bbe82606001516fffffffffffffffffffffffffffffffff1683600001516fffffffffffffffffffffffffffffffff16846020015163ffffffff1642611ba29190613609565b85608001516fffffffffffffffffffffffffffffffff166124fd565b6fffffffffffffffffffffffffffffffff1682525063ffffffff4216602082015290565b33600090815260096020526040902061084d90827f000000000000000000000000000000000000000000000000000000000000000061253b565b600482015163ffffffff811615611c67576040517f68d2f8d600000000000000000000000000000000000000000000000000000000815263ffffffff821660048201526024016106ec565b6008830151600c8401516014850151602085015163ffffffff808516911614611cd25760208501516040517fe366a11700000000000000000000000000000000000000000000000000000000815263ffffffff918216600482015290841660248201526044016106ec565b7f000000000000000000000000000000000000000000000000000000000000000063ffffffff168263ffffffff1614611d67576040517f77e4802600000000000000000000000000000000000000000000000000000000815263ffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152831660248201526044016106ec565b845167ffffffffffffffff828116911614611dc55784516040517ff917ffea00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff918216600482015290821660248201526044016106ec565b505050505050565b6060600061138c836128be565b33600090815260066020526040902061084d90827f000000000000000000000000000000000000000000000000000000000000000061253b565b611e1c611246565b60005b83811015612139576000858583818110611e3b57611e3b6131b1565b905060a00201803603810190611e519190613658565b9050806020015115612029578051611e6b906004906124db565b15611fdc576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526006909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f0b594bb0555ff7b252e0c789ccc9d8903fec294172064308727d570505cee1ac92611fcf929161334c565b60405180910390a1612128565b80516040517fd3eb6bc500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016106ec565b8051612037906004906124b9565b156120db57805173ffffffffffffffffffffffffffffffffffffffff1660009081526006602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517f7fd064821314ad863a0714a3f1229375ace6b6427ed5544b7b2ba1c47b1b529491611fcf9173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b80516040517f498f12f600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911660048201526024016106ec565b506121328161328b565b9050611e1f565b5060005b818110156123bd576000838383818110612159576121596131b1565b905060a0020180360381019061216f9190613658565b90508060200151156122fa578051612189906007906124db565b15611fdc576040805160a08101825282820180516020908101516fffffffffffffffffffffffffffffffff908116845263ffffffff4281168386019081528451511515868801908152855185015184166060880190815286518901518516608089019081528a5173ffffffffffffffffffffffffffffffffffffffff1660009081526009909752958990209751885493519251151574010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff939095167001000000000000000000000000000000009081027fffffffffffffffffffffffff0000000000000000000000000000000000000000909516918716919091179390931791909116929092178655905192518216029116176001909201919091558251905191517f395b7374909d2b54e5796f53c898ebf41d767c86c78ea86519acf2b805852d88926122ed929161334c565b60405180910390a16123ac565b8051612308906007906124b9565b156120db57805173ffffffffffffffffffffffffffffffffffffffff1660009081526009602052604080822080547fffffffffffffffffffffff00000000000000000000000000000000000000000016815560010191909155815190517fcf91daec21e3510e2f2aea4b09d08c235d5c6844980be709f282ef591dbf420c916122ed9173ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b506123b68161328b565b905061213d565b5050505050565b3373ffffffffffffffffffffffffffffffffffffffff821603612443576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016106ec565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061138c8373ffffffffffffffffffffffffffffffffffffffff841661291a565b600061138c8373ffffffffffffffffffffffffffffffffffffffff8416612a0d565b600061251c8561250d848661369d565b61251790876136b4565b612525565b95945050505050565b6000818310612534578161138c565b5090919050565b825474010000000000000000000000000000000000000000900460ff161580612562575081155b1561256c57505050565b825460018401546fffffffffffffffffffffffffffffffff808316929116906000906125b290700100000000000000000000000000000000900463ffffffff1642613609565b9050801561267257818311156125f4576040517f9725942a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600186015461262e9083908590849070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff166124fd565b86547fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000004263ffffffff160217875592505b848210156127295773ffffffffffffffffffffffffffffffffffffffff84166126d1576040517ff94ebcd100000000000000000000000000000000000000000000000000000000815260048101839052602481018690526044016106ec565b6040517f1a76572a000000000000000000000000000000000000000000000000000000008152600481018390526024810186905273ffffffffffffffffffffffffffffffffffffffff851660448201526064016106ec565b8483101561283c5760018681015470010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1690600090829061276d9082613609565b612777878a613609565b61278191906136b4565b61278b91906136c7565b905073ffffffffffffffffffffffffffffffffffffffff86166127e4576040517f15279c0800000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016106ec565b6040517fd0c8d23a000000000000000000000000000000000000000000000000000000008152600481018290526024810186905273ffffffffffffffffffffffffffffffffffffffff871660448201526064016106ec565b6128468584613609565b86547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff82161787556040518681529093507f1871cdf8010e63f2eb8384381a68dfa7416dc571a5517e66e88b2d2d0c0a690a9060200160405180910390a1505050505050565b60608160000180548060200260200160405190810160405280929190818152602001828054801561290e57602002820191906000526020600020905b8154815260200190600101908083116128fa575b50505050509050919050565b60008181526001830160205260408120548015612a0357600061293e600183613609565b855490915060009061295290600190613609565b90508181146129b7576000866000018281548110612972576129726131b1565b9060005260206000200154905080876000018481548110612995576129956131b1565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806129c8576129c8613702565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610829565b6000915050610829565b6000818152600183016020526040812054612a5457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610829565b506000610829565b60008060208385031215612a6f57600080fd5b823567ffffffffffffffff80821115612a8757600080fd5b818501915085601f830112612a9b57600080fd5b813581811115612aaa57600080fd5b8660208260071b8501011115612abf57600080fd5b60209290920196919550909350505050565b600060208284031215612ae357600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461138c57600080fd5b60005b83811015612b2e578181015183820152602001612b16565b50506000910152565b60008151808452612b4f816020860160208601612b13565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60208152600061138c6020830184612b37565b803573ffffffffffffffffffffffffffffffffffffffff81168114612bb857600080fd5b919050565b600060208284031215612bcf57600080fd5b61138c82612b94565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715612c2a57612c2a612bd8565b60405290565b6040805190810167ffffffffffffffff81118282101715612c2a57612c2a612bd8565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612c9a57612c9a612bd8565b604052919050565b63ffffffff8116811461084d57600080fd5b600060608284031215612cc657600080fd5b612cce612c07565b8235612cd981612ca2565b8152612ce760208401612b94565b6020820152612cf860408401612b94565b60408201529392505050565b60008083601f840112612d1657600080fd5b50813567ffffffffffffffff811115612d2e57600080fd5b6020830191508360208260051b8501011115612d4957600080fd5b9250929050565b60008060008060408587031215612d6657600080fd5b843567ffffffffffffffff80821115612d7e57600080fd5b612d8a88838901612d04565b90965094506020870135915080821115612da357600080fd5b50612db087828801612d04565b95989497509550505050565b801515811461084d57600080fd5b80356fffffffffffffffffffffffffffffffff81168114612bb857600080fd5b600060608284031215612dfc57600080fd5b612e04612c07565b90508135612e1181612dbc565b8152612e1f60208301612dca565b6020820152612e3060408301612dca565b604082015292915050565b60008060808385031215612e4e57600080fd5b612e5783612b94565b9150612e668460208501612dea565b90509250929050565b600067ffffffffffffffff821115612e8957612e89612bd8565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112612ec657600080fd5b8135612ed9612ed482612e6f565b612c53565b818152846020838601011115612eee57600080fd5b816020850160208301376000918101602001919091529392505050565b67ffffffffffffffff8116811461084d57600080fd5b600080600080600060a08688031215612f3957600080fd5b853567ffffffffffffffff80821115612f5157600080fd5b612f5d89838a01612eb5565b9650612f6b60208901612b94565b95506040880135945060608801359150612f8482612f0b565b90925060808701359080821115612f9a57600080fd5b50612fa788828901612eb5565b9150509295509295909350565b6020808252825182820181905260009190848201906040850190845b8181101561300257835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612fd0565b50909695505050505050565b60008083601f84011261302057600080fd5b50813567ffffffffffffffff81111561303857600080fd5b602083019150836020828501011115612d4957600080fd5b600080600080600080600060a0888a03121561306b57600080fd5b61307488612b94565b9650602088013567ffffffffffffffff8082111561309157600080fd5b61309d8b838c0161300e565b909850965060408a0135955060608a013591506130b982612f0b565b909350608089013590808211156130cf57600080fd5b506130dc8a828b0161300e565b989b979a50959850939692959293505050565b60008083601f84011261310157600080fd5b50813567ffffffffffffffff81111561311957600080fd5b60208301915083602060a083028501011115612d4957600080fd5b6000806000806040858703121561314a57600080fd5b843567ffffffffffffffff8082111561316257600080fd5b61316e888389016130ef565b9096509450602087013591508082111561318757600080fd5b50612db0878288016130ef565b6000602082840312156131a657600080fd5b813561138c81612f0b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000608082840312156131f257600080fd5b6040516080810181811067ffffffffffffffff8211171561321557613215612bd8565b60405282358152602083013561322a81612ca2565b6020820152604083013561323d81612f0b565b6040820152606083013561325081612dbc565b60608201529392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036132bc576132bc61325c565b5060010190565b6020808252818101839052600090604080840186845b8781101561333f5781358352848201356132f281612ca2565b63ffffffff16838601528184013561330981612f0b565b67ffffffffffffffff168385015260608281013561332681612dbc565b15159084015260809283019291909101906001016132d9565b5090979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff831681526080810161138c60208301848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600082601f8301126133b557600080fd5b81516133c3612ed482612e6f565b8181528460208386010111156133d857600080fd5b6133e9826020830160208701612b13565b949350505050565b6000806040838503121561340457600080fd5b825167ffffffffffffffff8082111561341c57600080fd5b613428868387016133a4565b9350602085015191508082111561343e57600080fd5b5061344b858286016133a4565b9150509250929050565b60006040828403121561346757600080fd5b61346f612c30565b825161347a81612f0b565b8152602083015161348a81612ca2565b60208201529392505050565b6000602082840312156134a857600080fd5b815167ffffffffffffffff808211156134c057600080fd5b90830190604082860312156134d457600080fd5b6134dc612c30565b8251828111156134eb57600080fd5b6134f7878286016133a4565b82525060208301518281111561350c57600080fd5b613518878286016133a4565b60208301525095945050505050565b60408152600061353a6040830185612b37565b828103602084015261251c8185612b37565b60006020828403121561355e57600080fd5b815161138c81612dbc565b6000808585111561357957600080fd5b8386111561358657600080fd5b5050820193919092039150565b80356020831015610829577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b1692915050565b6000602082840312156135e157600080fd5b815161138c81612f0b565b6000602082840312156135fe57600080fd5b815161138c81612ca2565b818103818111156108295761082961325c565b6060810161082982848051151582526020808201516fffffffffffffffffffffffffffffffff9081169184019190915260409182015116910152565b600060a0828403121561366a57600080fd5b613672612c07565b61367b83612b94565b8152602083013561368b81612dbc565b6020820152612cf88460408501612dea565b80820281158282048414176108295761082961325c565b808201808211156108295761082961325c565b6000826136fd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000813000a", } var USDCTokenPoolABI = USDCTokenPoolMetaData.ABI @@ -584,6 +584,28 @@ func (_USDCTokenPool *USDCTokenPoolCallerSession) SupportsInterface(interfaceId return _USDCTokenPool.Contract.SupportsInterface(&_USDCTokenPool.CallOpts, interfaceId) } +func (_USDCTokenPool *USDCTokenPoolCaller) TypeAndVersion(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _USDCTokenPool.contract.Call(opts, &out, "typeAndVersion") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_USDCTokenPool *USDCTokenPoolSession) TypeAndVersion() (string, error) { + return _USDCTokenPool.Contract.TypeAndVersion(&_USDCTokenPool.CallOpts) +} + +func (_USDCTokenPool *USDCTokenPoolCallerSession) TypeAndVersion() (string, error) { + return _USDCTokenPool.Contract.TypeAndVersion(&_USDCTokenPool.CallOpts) +} + func (_USDCTokenPool *USDCTokenPoolTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { return _USDCTokenPool.contract.Transact(opts, "acceptOwnership") } @@ -2823,6 +2845,8 @@ type USDCTokenPoolInterface interface { SupportsInterface(opts *bind.CallOpts, interfaceId [4]byte) (bool, error) + TypeAndVersion(opts *bind.CallOpts) (string, error) + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) ApplyAllowListUpdates(opts *bind.TransactOpts, removes []common.Address, adds []common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 3397089b9e..089366d9b7 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -1,18 +1,18 @@ GETH_VERSION: 1.12.0 arm_contract: ../../../contracts/solc/v0.8.19/ARM.abi ../../../contracts/solc/v0.8.19/ARM.bin 893a2d007f5ffad2a118beccee72cf28913a2d6207f22b2028543139a5fdece0 arm_proxy_contract: ../../../contracts/solc/v0.8.19/ARMProxy.abi ../../../contracts/solc/v0.8.19/ARMProxy.bin f7b818c2ba31d8b12ea2dbaebc72c74e69640b7349b76c7415226cc4946075f2 -burn_mint_token_pool: ../../../contracts/solc/v0.8.19/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.19/BurnMintTokenPool.bin aa87ca3c7881b7739b2b4677069f7293cad99b2e8342041b900d8cd49f2655fb -commit_store: ../../../contracts/solc/v0.8.19/CommitStore.abi ../../../contracts/solc/v0.8.19/CommitStore.bin 7d80f085f8249ef15e0850bf03698806c972125156f3476a1dafca54598f7f4d -commit_store_helper: ../../../contracts/solc/v0.8.19/CommitStoreHelper.abi ../../../contracts/solc/v0.8.19/CommitStoreHelper.bin 0891a1662bda54db424d12e80a56533cfd9859f7d94a3be147ad3caa46cad072 +burn_mint_token_pool: ../../../contracts/solc/v0.8.19/BurnMintTokenPool.abi ../../../contracts/solc/v0.8.19/BurnMintTokenPool.bin 947de112c634df5aa5a5b3d82fe89a9dc7d9f1f4864a8c054ca71dd8fa73b25e +commit_store: ../../../contracts/solc/v0.8.19/CommitStore.abi ../../../contracts/solc/v0.8.19/CommitStore.bin b971b915b36bdc5e4ce8aee6bb5ae7a5cdedc562874f87ca863c96c2529fcc5b +commit_store_helper: ../../../contracts/solc/v0.8.19/CommitStoreHelper.abi ../../../contracts/solc/v0.8.19/CommitStoreHelper.bin dd078eef6a55928e0cad79f40828a36cfa5c2789a664f37b56a7c215fb7c8932 custom_token_pool: ../../../contracts/solc/v0.8.19/CustomTokenPool.abi ../../../contracts/solc/v0.8.19/CustomTokenPool.bin 79ab937aa4493bf31fb0e57affd00555aad75205c90268e89674c28ea9e5e48f -evm_2_evm_offramp: ../../../contracts/solc/v0.8.19/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.19/EVM2EVMOffRamp.bin 8a0bd8a428ae8d071d326a2d4e1f7a2d35da08fef7307b6e1f15e108eb23770e -evm_2_evm_offramp_helper: ../../../contracts/solc/v0.8.19/EVM2EVMOffRampHelper.abi ../../../contracts/solc/v0.8.19/EVM2EVMOffRampHelper.bin 9e06fb409bcc9b1728c1a327d404640796c2834e7798728224b8ad4e5745c4a7 -evm_2_evm_onramp: ../../../contracts/solc/v0.8.19/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.19/EVM2EVMOnRamp.bin 1c21fbc9b49521a9a783c40b0674297bfcb18a64100dae10173682e38ea199fc -lock_release_token_pool: ../../../contracts/solc/v0.8.19/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.19/LockReleaseTokenPool.bin 7f7a28f55f9fb63669cd8038a7f99e31431acd6d15ddeeb6a77188eb0bf85d58 +evm_2_evm_offramp: ../../../contracts/solc/v0.8.19/EVM2EVMOffRamp.abi ../../../contracts/solc/v0.8.19/EVM2EVMOffRamp.bin bfea579e0b5100b6e90c2ea4d1533789ff037104fd03ba590e135772a0cf0997 +evm_2_evm_offramp_helper: ../../../contracts/solc/v0.8.19/EVM2EVMOffRampHelper.abi ../../../contracts/solc/v0.8.19/EVM2EVMOffRampHelper.bin fe22966f5d97a8f386a4f01f901a308592336ea52c8fd06311f4bf1a961033ad +evm_2_evm_onramp: ../../../contracts/solc/v0.8.19/EVM2EVMOnRamp.abi ../../../contracts/solc/v0.8.19/EVM2EVMOnRamp.bin 16e8043f787ecb8e0728d48f051583527fbd19fd1e57f0414c427972db92005d +lock_release_token_pool: ../../../contracts/solc/v0.8.19/LockReleaseTokenPool.abi ../../../contracts/solc/v0.8.19/LockReleaseTokenPool.bin 5a60f3e6d803cbd7581f6a9a1e34934ba6bce065454265d1039d92af5592a2e8 maybe_revert_message_receiver: ../../../contracts/solc/v0.8.19/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.19/MaybeRevertMessageReceiver.bin aaa90eac8cc555ee4b0fbe57d1fb8d72d6689b29510b238177c97ab9b7979ac5 mock_arm_contract: ../../../contracts/solc/v0.8.19/MockARM.abi ../../../contracts/solc/v0.8.19/MockARM.bin efcf4cb260a2b6a6e189639f62bb50ab650a135715c1fcd42c92dfa9d04aa0e3 ping_pong_demo: ../../../contracts/solc/v0.8.19/PingPongDemo.abi ../../../contracts/solc/v0.8.19/PingPongDemo.bin f2972aa082cee8b461122f79773ce247d23b551ddc2ca9926ae90624134cfb23 -price_registry: ../../../contracts/solc/v0.8.19/PriceRegistry.abi ../../../contracts/solc/v0.8.19/PriceRegistry.bin 61e69348939585a4310e482a0f548149e1121527b378a3a76b988e59b0465c66 +price_registry: ../../../contracts/solc/v0.8.19/PriceRegistry.abi ../../../contracts/solc/v0.8.19/PriceRegistry.bin 36e8d2c44a16fefb5258557cb1eae25eca1cc12efcd3c3270f91a90a5f81e7ea router: ../../../contracts/solc/v0.8.19/Router.abi ../../../contracts/solc/v0.8.19/Router.bin 29690cda0fbe8ea7215132d65082c1987a3f27baebcdd8fff8f04df5e3712d00 -usdc_token_pool: ../../../contracts/solc/v0.8.19/USDCTokenPool.abi ../../../contracts/solc/v0.8.19/USDCTokenPool.bin 36fb183677c717bf91673eb83c080449fd5d9ea11f2a5dd14ee6a63889ec6f33 +usdc_token_pool: ../../../contracts/solc/v0.8.19/USDCTokenPool.abi ../../../contracts/solc/v0.8.19/USDCTokenPool.bin dd7e1adb7e9bcfafe86721206ebf84dbfedf236adf0040b853d30575c207f3e4 weth9: ../../../contracts/solc/v0.8.19/WETH9.abi ../../../contracts/solc/v0.8.19/WETH9.bin 5a7d64fb19b62ec523c7667ce4c2983295c05f74935b5f994c06a6f70d440f8b diff --git a/core/gethwrappers/generated/batch_blockhash_store/batch_blockhash_store.go b/core/gethwrappers/generated/batch_blockhash_store/batch_blockhash_store.go index 9f799c4937..426c5a2c79 100644 --- a/core/gethwrappers/generated/batch_blockhash_store/batch_blockhash_store.go +++ b/core/gethwrappers/generated/batch_blockhash_store/batch_blockhash_store.go @@ -30,7 +30,7 @@ var ( var BatchBlockhashStoreMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStoreAddr\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BHS\",\"outputs\":[{\"internalType\":\"contractBlockhashStore\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"blockNumbers\",\"type\":\"uint256[]\"}],\"name\":\"getBlockhashes\",\"outputs\":[{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"blockNumbers\",\"type\":\"uint256[]\"}],\"name\":\"store\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"blockNumbers\",\"type\":\"uint256[]\"},{\"internalType\":\"bytes[]\",\"name\":\"headers\",\"type\":\"bytes[]\"}],\"name\":\"storeVerifyHeader\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a060405234801561001057600080fd5b50604051610b81380380610b8183398101604081905261002f91610044565b60601b6001600160601b031916608052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160601c610adb6100a66000396000818160a7015281816101270152818161023a01526104290152610adb6000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306bd010d146100515780631f600f86146100665780635d290e211461008f578063f745eafb146100a2575b600080fd5b61006461005f366004610654565b6100ee565b005b610079610074366004610654565b6101e2565b60405161008691906107ff565b60405180910390f35b61006461009d366004610691565b6103ac565b6100c97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610086565b60005b81518110156101de5761011c82828151811061010f5761010f6109ac565b60200260200101516104fe565b610125576101cc565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636057361d838381518110610173576101736109ac565b60200260200101516040518263ffffffff1660e01b815260040161019991815260200190565b600060405180830381600087803b1580156101b357600080fd5b505af11580156101c7573d6000803e3d6000fd5b505050505b806101d681610944565b9150506100f1565b5050565b60606000825167ffffffffffffffff811115610200576102006109db565b604051908082528060200260200182016040528015610229578160200160208202803683370190505b50905060005b83518110156103a5577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e9413d38858381518110610286576102866109ac565b60200260200101516040518263ffffffff1660e01b81526004016102ac91815260200190565b60206040518083038186803b1580156102c457600080fd5b505afa925050508015610312575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261030f918101906107e6565b60015b6103725761031e610a0a565b806308c379a014156103665750610333610a26565b8061033e5750610368565b6000801b838381518110610354576103546109ac565b60200260200101818152505050610393565b505b3d6000803e3d6000fd5b80838381518110610385576103856109ac565b602002602001018181525050505b8061039d81610944565b91505061022f565b5092915050565b805182511461041b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f696e70757420617272617920617267206c656e67746873206d69736d61746368604482015260640160405180910390fd5b60005b82518110156104f9577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fadff0e1848381518110610475576104756109ac565b602002602001015184848151811061048f5761048f6109ac565b60200260200101516040518363ffffffff1660e01b81526004016104b4929190610843565b600060405180830381600087803b1580156104ce57600080fd5b505af11580156104e2573d6000803e3d6000fd5b5050505080806104f190610944565b91505061041e565b505050565b600061010061050b610537565b111561052e5761010061051c610537565b61052691906108e2565b821015610531565b60015b92915050565b60004661a4b181148061054c575062066eed81145b156105d657606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561059857600080fd5b505afa1580156105ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d091906107e6565b91505090565b4391505090565b600082601f8301126105ee57600080fd5b813560206105fb826108be565b60405161060882826108f9565b8381528281019150858301600585901b8701840188101561062857600080fd5b60005b858110156106475781358452928401929084019060010161062b565b5090979650505050505050565b60006020828403121561066657600080fd5b813567ffffffffffffffff81111561067d57600080fd5b610689848285016105dd565b949350505050565b60008060408084860312156106a557600080fd5b833567ffffffffffffffff808211156106bd57600080fd5b6106c9878388016105dd565b94506020915081860135818111156106e057600080fd5b8601601f810188136106f157600080fd5b80356106fc816108be565b855161070882826108f9565b8281528581019150838601600584901b850187018c101561072857600080fd5b60005b848110156107d45781358781111561074257600080fd5b8601603f81018e1361075357600080fd5b8881013588811115610767576107676109db565b8a5161079a8b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85011601826108f9565b8181528f8c8385010111156107ae57600080fd5b818c84018c83013760009181018b0191909152855250928701929087019060010161072b565b50989b909a5098505050505050505050565b6000602082840312156107f857600080fd5b5051919050565b6020808252825182820181905260009190848201906040850190845b818110156108375783518352928401929184019160010161081b565b50909695505050505050565b82815260006020604081840152835180604085015260005b818110156108775785810183015185820160600152820161085b565b81811115610889576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201606001949350505050565b600067ffffffffffffffff8211156108d8576108d86109db565b5060051b60200190565b6000828210156108f4576108f461097d565b500390565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff8211171561093d5761093d6109db565b6040525050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156109765761097661097d565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115610a235760046000803e5060005160e01c5b90565b600060443d1015610a345790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff8160248401118184111715610a8257505050505090565b8285019150815181811115610a9a5750505050505090565b843d8701016020828501011115610ab45750505050505090565b610ac3602082860101876108f9565b50909594505050505056fea164736f6c6343000806000a", + Bin: "0x60a060405234801561001057600080fd5b50604051610b9b380380610b9b83398101604081905261002f91610044565b60601b6001600160601b031916608052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160601c610af56100a66000396000818160a7015281816101270152818161023a01526104290152610af56000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806306bd010d146100515780631f600f86146100665780635d290e211461008f578063f745eafb146100a2575b600080fd5b61006461005f36600461066e565b6100ee565b005b61007961007436600461066e565b6101e2565b6040516100869190610819565b60405180910390f35b61006461009d3660046106ab565b6103ac565b6100c97f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610086565b60005b81518110156101de5761011c82828151811061010f5761010f6109c6565b60200260200101516104fe565b610125576101cc565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636057361d838381518110610173576101736109c6565b60200260200101516040518263ffffffff1660e01b815260040161019991815260200190565b600060405180830381600087803b1580156101b357600080fd5b505af11580156101c7573d6000803e3d6000fd5b505050505b806101d68161095e565b9150506100f1565b5050565b60606000825167ffffffffffffffff811115610200576102006109f5565b604051908082528060200260200182016040528015610229578160200160208202803683370190505b50905060005b83518110156103a5577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663e9413d38858381518110610286576102866109c6565b60200260200101516040518263ffffffff1660e01b81526004016102ac91815260200190565b60206040518083038186803b1580156102c457600080fd5b505afa925050508015610312575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820190925261030f91810190610800565b60015b6103725761031e610a24565b806308c379a014156103665750610333610a40565b8061033e5750610368565b6000801b838381518110610354576103546109c6565b60200260200101818152505050610393565b505b3d6000803e3d6000fd5b80838381518110610385576103856109c6565b602002602001018181525050505b8061039d8161095e565b91505061022f565b5092915050565b805182511461041b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f696e70757420617272617920617267206c656e67746873206d69736d61746368604482015260640160405180910390fd5b60005b82518110156104f9577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663fadff0e1848381518110610475576104756109c6565b602002602001015184848151811061048f5761048f6109c6565b60200260200101516040518363ffffffff1660e01b81526004016104b492919061085d565b600060405180830381600087803b1580156104ce57600080fd5b505af11580156104e2573d6000803e3d6000fd5b5050505080806104f19061095e565b91505061041e565b505050565b600061010061050b610537565b111561052e5761010061051c610537565b61052691906108fc565b821015610531565b60015b92915050565b600046610543816105d4565b156105cd57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561058f57600080fd5b505afa1580156105a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105c79190610800565b91505090565b4391505090565b600061a4b18214806105e8575062066eed82145b8061053157505062066eee1490565b600082601f83011261060857600080fd5b81356020610615826108d8565b6040516106228282610913565b8381528281019150858301600585901b8701840188101561064257600080fd5b60005b8581101561066157813584529284019290840190600101610645565b5090979650505050505050565b60006020828403121561068057600080fd5b813567ffffffffffffffff81111561069757600080fd5b6106a3848285016105f7565b949350505050565b60008060408084860312156106bf57600080fd5b833567ffffffffffffffff808211156106d757600080fd5b6106e3878388016105f7565b94506020915081860135818111156106fa57600080fd5b8601601f8101881361070b57600080fd5b8035610716816108d8565b85516107228282610913565b8281528581019150838601600584901b850187018c101561074257600080fd5b60005b848110156107ee5781358781111561075c57600080fd5b8601603f81018e1361076d57600080fd5b8881013588811115610781576107816109f5565b8a516107b48b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8501160182610913565b8181528f8c8385010111156107c857600080fd5b818c84018c83013760009181018b01919091528552509287019290870190600101610745565b50989b909a5098505050505050505050565b60006020828403121561081257600080fd5b5051919050565b6020808252825182820181905260009190848201906040850190845b8181101561085157835183529284019291840191600101610835565b50909695505050505050565b82815260006020604081840152835180604085015260005b8181101561089157858101830151858201606001528201610875565b818111156108a3576000606083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01692909201606001949350505050565b600067ffffffffffffffff8211156108f2576108f26109f5565b5060051b60200190565b60008282101561090e5761090e610997565b500390565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f830116810181811067ffffffffffffffff82111715610957576109576109f5565b6040525050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561099057610990610997565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115610a3d5760046000803e5060005160e01c5b90565b600060443d1015610a4e5790565b6040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc803d016004833e81513d67ffffffffffffffff8160248401118184111715610a9c57505050505090565b8285019150815181811115610ab45750505050505090565b843d8701016020828501011115610ace5750505050505090565b610add60208286010187610913565b50909594505050505056fea164736f6c6343000806000a", } var BatchBlockhashStoreABI = BatchBlockhashStoreMetaData.ABI diff --git a/core/gethwrappers/generated/trusted_blockhash_store/trusted_blockhash_store.go b/core/gethwrappers/generated/trusted_blockhash_store/trusted_blockhash_store.go index 27f7c4ebbb..43ae1a3f5b 100644 --- a/core/gethwrappers/generated/trusted_blockhash_store/trusted_blockhash_store.go +++ b/core/gethwrappers/generated/trusted_blockhash_store/trusted_blockhash_store.go @@ -32,7 +32,7 @@ var ( 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: "0x60806040523480156200001157600080fd5b50604051620014e8380380620014e88339810160408190526200003491620003e8565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018560201b60201c565b5062000517565b6001600160a01b038116331415620001345760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018f620002ec565b60006004805480602002602001604051908101604052809291908181526020018280548015620001e957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620001ca575b5050855193945062000207936004935060208701925090506200034a565b5060005b81518110156200027757600060036000848481518110620002305762000230620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806200026e81620004c1565b9150506200020b565b5060005b8251811015620002e757600160036000858481518110620002a057620002a0620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580620002de81620004c1565b9150506200027b565b505050565b6000546001600160a01b03163314620003485760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b828054828255906000526020600020908101928215620003a2579160200282015b82811115620003a257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200036b565b50620003b0929150620003b4565b5090565b5b80821115620003b05760008155600101620003b5565b80516001600160a01b0381168114620003e357600080fd5b919050565b60006020808385031215620003fc57600080fd5b82516001600160401b03808211156200041457600080fd5b818501915085601f8301126200042957600080fd5b8151818111156200043e576200043e62000501565b8060051b604051601f19603f8301168101818110858211171562000466576200046662000501565b604052828152858101935084860182860187018a10156200048657600080fd5b600095505b83861015620004b4576200049f81620003cb565b8552600195909501949386019386016200048b565b5098975050505050505050565b6000600019821415620004e457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b610fc180620005276000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b5578063f4217648146101c8578063fadff0e1146101db57600080fd5b80638da5cb5b14610143578063e9413d3814610161578063e9ecc1541461018257600080fd5b80636057361d116100b25780636057361d1461012057806379ba50971461013357806383b6d6b71461013b57600080fd5b80633b69ad60146100ce5780635c7de309146100e3575b600080fd5b6100e16100dc366004610d03565b6101ee565b005b6100f66100f1366004610d9a565b610326565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100e161012e366004610d9a565b61035d565b6100e16103e8565b6100e16104e5565b60005473ffffffffffffffffffffffffffffffffffffffff166100f6565b61017461016f366004610d9a565b6104ff565b604051908152602001610117565b6101a5610190366004610c34565b60036020526000908152604090205460ff1681565b6040519015158152602001610117565b6100e16101c3366004610c34565b61057b565b6100e16101d6366004610c4f565b61058f565b6100e16101e9366004610db3565b610745565b60006101f9836107e8565b9050818114610234576040517fd2f69c9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526003602052604090205460ff1661027d576040517f5b0aa2ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8584146102b6576040517fbd75093300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8681101561031c578585828181106102d3576102d3610f56565b90506020020135600260008a8a858181106102f0576102f0610f56565b90506020020135815260200190815260200160002081905550808061031490610eee565b9150506102b9565b5050505050505050565b6004818154811061033657600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000610368826107e8565b9050806103d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f626c6f636b68617368286e29206661696c65640000000000000000000000000060448201526064015b60405180910390fd5b60009182526002602052604090912055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610469576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103cd565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104fd6101006104f3610903565b61012e9190610ed7565b565b60008181526002602052604081205480610575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f626c6f636b68617368206e6f7420666f756e6420696e2073746f72650000000060448201526064016103cd565b92915050565b6105836109a9565b61058c81610a2a565b50565b6105976109a9565b600060048054806020026020016040519081016040528092919081815260200182805480156105fc57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116105d1575b5050855193945061061893600493506020870192509050610b20565b5060005b81518110156106ac5760006003600084848151811061063d5761063d610f56565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806106a481610eee565b91505061061c565b5060005b8251811015610740576001600360008584815181106106d1576106d1610f56565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558061073881610eee565b9150506106b0565b505050565b60026000610754846001610ebf565b8152602001908152602001600020548180519060200120146107d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6865616465722068617320756e6b6e6f776e20626c6f636b686173680000000060448201526064016103cd565b6024015160009182526002602052604090912055565b60004661a4b18114806107fd575062066eed81145b8061080a575062066eee81145b156108f3576101008367ffffffffffffffff16610825610903565b61082f9190610ed7565b118061084c575061083e610903565b8367ffffffffffffffff1610155b1561085a5750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b1580156108b457600080fd5b505afa1580156108c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ec9190610d81565b9392505050565b505067ffffffffffffffff164090565b60004661a4b1811480610918575062066eed81145b156109a257606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561096457600080fd5b505afa158015610978573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099c9190610d81565b91505090565b4391505090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103cd565b73ffffffffffffffffffffffffffffffffffffffff8116331415610aaa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103cd565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610b9a579160200282015b82811115610b9a57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610b40565b50610ba6929150610baa565b5090565b5b80821115610ba65760008155600101610bab565b803573ffffffffffffffffffffffffffffffffffffffff81168114610be357600080fd5b919050565b60008083601f840112610bfa57600080fd5b50813567ffffffffffffffff811115610c1257600080fd5b6020830191508360208260051b8501011115610c2d57600080fd5b9250929050565b600060208284031215610c4657600080fd5b6108ec82610bbf565b60006020808385031215610c6257600080fd5b823567ffffffffffffffff80821115610c7a57600080fd5b818501915085601f830112610c8e57600080fd5b813581811115610ca057610ca0610f85565b8060051b9150610cb1848301610e70565b8181528481019084860184860187018a1015610ccc57600080fd5b600095505b83861015610cf657610ce281610bbf565b835260019590950194918601918601610cd1565b5098975050505050505050565b60008060008060008060808789031215610d1c57600080fd5b863567ffffffffffffffff80821115610d3457600080fd5b610d408a838b01610be8565b90985096506020890135915080821115610d5957600080fd5b50610d6689828a01610be8565b979a9699509760408101359660609091013595509350505050565b600060208284031215610d9357600080fd5b5051919050565b600060208284031215610dac57600080fd5b5035919050565b60008060408385031215610dc657600080fd5b8235915060208084013567ffffffffffffffff80821115610de657600080fd5b818601915086601f830112610dfa57600080fd5b813581811115610e0c57610e0c610f85565b610e3c847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610e70565b91508082528784828501011115610e5257600080fd5b80848401858401376000848284010152508093505050509250929050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610eb757610eb7610f85565b604052919050565b60008219821115610ed257610ed2610f27565b500190565b600082821015610ee957610ee9610f27565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f2057610f20610f27565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", + Bin: "0x60806040523480156200001157600080fd5b50604051620014ec380380620014ec8339810160408190526200003491620003e8565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d9565b505050620000d2816200018560201b60201c565b5062000517565b6001600160a01b038116331415620001345760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200018f620002ec565b60006004805480602002602001604051908101604052809291908181526020018280548015620001e957602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620001ca575b5050855193945062000207936004935060208701925090506200034a565b5060005b81518110156200027757600060036000848481518110620002305762000230620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055806200026e81620004c1565b9150506200020b565b5060005b8251811015620002e757600160036000858481518110620002a057620002a0620004eb565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905580620002de81620004c1565b9150506200027b565b505050565b6000546001600160a01b03163314620003485760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000082565b565b828054828255906000526020600020908101928215620003a2579160200282015b82811115620003a257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906200036b565b50620003b0929150620003b4565b5090565b5b80821115620003b05760008155600101620003b5565b80516001600160a01b0381168114620003e357600080fd5b919050565b60006020808385031215620003fc57600080fd5b82516001600160401b03808211156200041457600080fd5b818501915085601f8301126200042957600080fd5b8151818111156200043e576200043e62000501565b8060051b604051601f19603f8301168101818110858211171562000466576200046662000501565b604052828152858101935084860182860187018a10156200048657600080fd5b600095505b83861015620004b4576200049f81620003cb565b8552600195909501949386019386016200048b565b5098975050505050505050565b6000600019821415620004e457634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b610fc580620005276000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c80638da5cb5b11610081578063f2fde38b1161005b578063f2fde38b146101b5578063f4217648146101c8578063fadff0e1146101db57600080fd5b80638da5cb5b14610143578063e9413d3814610161578063e9ecc1541461018257600080fd5b80636057361d116100b25780636057361d1461012057806379ba50971461013357806383b6d6b71461013b57600080fd5b80633b69ad60146100ce5780635c7de309146100e3575b600080fd5b6100e16100dc366004610d07565b6101ee565b005b6100f66100f1366004610d9e565b610326565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100e161012e366004610d9e565b61035d565b6100e16103e8565b6100e16104e5565b60005473ffffffffffffffffffffffffffffffffffffffff166100f6565b61017461016f366004610d9e565b6104ff565b604051908152602001610117565b6101a5610190366004610c38565b60036020526000908152604090205460ff1681565b6040519015158152602001610117565b6100e16101c3366004610c38565b61057b565b6100e16101d6366004610c53565b61058f565b6100e16101e9366004610db7565b610745565b60006101f9836107e8565b9050818114610234576040517fd2f69c9500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360009081526003602052604090205460ff1661027d576040517f5b0aa2ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8584146102b6576040517fbd75093300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8681101561031c578585828181106102d3576102d3610f5a565b90506020020135600260008a8a858181106102f0576102f0610f5a565b90506020020135815260200190815260200160002081905550808061031490610ef2565b9150506102b9565b5050505050505050565b6004818154811061033657600080fd5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6000610368826107e8565b9050806103d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f626c6f636b68617368286e29206661696c65640000000000000000000000000060448201526064015b60405180910390fd5b60009182526002602052604090912055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610469576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103cd565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104fd6101006104f36108ed565b61012e9190610edb565b565b60008181526002602052604081205480610575576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f626c6f636b68617368206e6f7420666f756e6420696e2073746f72650000000060448201526064016103cd565b92915050565b61058361098a565b61058c81610a0b565b50565b61059761098a565b600060048054806020026020016040519081016040528092919081815260200182805480156105fc57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116105d1575b5050855193945061061893600493506020870192509050610b24565b5060005b81518110156106ac5760006003600084848151811061063d5761063d610f5a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055806106a481610ef2565b91505061061c565b5060005b8251811015610740576001600360008584815181106106d1576106d1610f5a565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff16825281019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558061073881610ef2565b9150506106b0565b505050565b60026000610754846001610ec3565b8152602001908152602001600020548180519060200120146107d2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f6865616465722068617320756e6b6e6f776e20626c6f636b686173680000000060448201526064016103cd565b6024015160009182526002602052604090912055565b6000466107f481610b01565b156108dd576101008367ffffffffffffffff1661080f6108ed565b6108199190610edb565b118061083657506108286108ed565b8367ffffffffffffffff1610155b156108445750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b15801561089e57600080fd5b505afa1580156108b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108d69190610d85565b9392505050565b505067ffffffffffffffff164090565b6000466108f981610b01565b1561098357606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561094557600080fd5b505afa158015610959573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061097d9190610d85565b91505090565b4391505090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103cd565b73ffffffffffffffffffffffffffffffffffffffff8116331415610a8b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103cd565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061a4b1821480610b15575062066eed82145b8061057557505062066eee1490565b828054828255906000526020600020908101928215610b9e579160200282015b82811115610b9e57825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610b44565b50610baa929150610bae565b5090565b5b80821115610baa5760008155600101610baf565b803573ffffffffffffffffffffffffffffffffffffffff81168114610be757600080fd5b919050565b60008083601f840112610bfe57600080fd5b50813567ffffffffffffffff811115610c1657600080fd5b6020830191508360208260051b8501011115610c3157600080fd5b9250929050565b600060208284031215610c4a57600080fd5b6108d682610bc3565b60006020808385031215610c6657600080fd5b823567ffffffffffffffff80821115610c7e57600080fd5b818501915085601f830112610c9257600080fd5b813581811115610ca457610ca4610f89565b8060051b9150610cb5848301610e74565b8181528481019084860184860187018a1015610cd057600080fd5b600095505b83861015610cfa57610ce681610bc3565b835260019590950194918601918601610cd5565b5098975050505050505050565b60008060008060008060808789031215610d2057600080fd5b863567ffffffffffffffff80821115610d3857600080fd5b610d448a838b01610bec565b90985096506020890135915080821115610d5d57600080fd5b50610d6a89828a01610bec565b979a9699509760408101359660609091013595509350505050565b600060208284031215610d9757600080fd5b5051919050565b600060208284031215610db057600080fd5b5035919050565b60008060408385031215610dca57600080fd5b8235915060208084013567ffffffffffffffff80821115610dea57600080fd5b818601915086601f830112610dfe57600080fd5b813581811115610e1057610e10610f89565b610e40847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601610e74565b91508082528784828501011115610e5657600080fd5b80848401858401376000848284010152508093505050509250929050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610ebb57610ebb610f89565b604052919050565b60008219821115610ed657610ed6610f2b565b500190565b600082821015610eed57610eed610f2b565b500390565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f2457610f24610f2b565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var TrustedBlockhashStoreABI = TrustedBlockhashStoreMetaData.ABI diff --git a/core/gethwrappers/generated/vrf_coordinator_v2/vrf_coordinator_v2.go b/core/gethwrappers/generated/vrf_coordinator_v2/vrf_coordinator_v2.go index 51021b789e..0a64747917 100644 --- a/core/gethwrappers/generated/vrf_coordinator_v2/vrf_coordinator_v2.go +++ b/core/gethwrappers/generated/vrf_coordinator_v2/vrf_coordinator_v2.go @@ -64,7 +64,7 @@ type VRFProof struct { var VRFCoordinatorV2MetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkEthFeed\",\"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\":\"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\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"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\":[{\"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\":\"fulfillmentFlatFeeLinkPPMTier1\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier2\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier3\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier4\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier5\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier2\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier3\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier4\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier5\",\"type\":\"uint24\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinatorV2.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"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\":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\":\"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\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"},{\"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\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subId\",\"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\":\"subId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"subId\",\"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\":\"subId\",\"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\":\"subId\",\"type\":\"uint64\"},{\"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\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subId\",\"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\":\"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\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"internalType\":\"structVRFCoordinatorV2.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"name\":\"getCommitment\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"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\":\"getCurrentSubId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getFeeConfig\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier1\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier2\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier3\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier4\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier5\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier2\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier3\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier4\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier5\",\"type\":\"uint24\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"}],\"name\":\"getFeeTier\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"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\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"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\":[],\"name\":\"getTotalBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"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\":\"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\":\"subId\",\"type\":\"uint64\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subId\",\"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\":\"address\",\"name\":\"oracle\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"subId\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"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\":\"fulfillmentFlatFeeLinkPPMTier1\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier2\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier3\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier4\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPMTier5\",\"type\":\"uint32\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier2\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier3\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier4\",\"type\":\"uint24\"},{\"internalType\":\"uint24\",\"name\":\"reqsForTier5\",\"type\":\"uint24\"}],\"internalType\":\"structVRFCoordinatorV2.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"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\"}]", - Bin: "0x60e06040523480156200001157600080fd5b50604051620059c1380380620059c18339810160408190526200003491620001b1565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e8565b5050506001600160601b0319606093841b811660805290831b811660a052911b1660c052620001fb565b6001600160a01b038116331415620001435760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ac57600080fd5b919050565b600080600060608486031215620001c757600080fd5b620001d28462000194565b9250620001e26020850162000194565b9150620001f26040850162000194565b90509250925092565b60805160601c60a05160601c60c05160601c61575c620002656000396000818161051901526138f00152600081816106030152613e0801526000818161036d015281816114da0152818161237701528181612dae01528181612eea015261350f015261575c6000f3fe608060405234801561001057600080fd5b506004361061025b5760003560e01c80636f64f03f11610145578063ad178361116100bd578063d2f9f9a71161008c578063e72f6e3011610071578063e72f6e30146106e0578063e82ad7d4146106f3578063f2fde38b1461071657600080fd5b8063d2f9f9a7146106ba578063d7ae1d30146106cd57600080fd5b8063ad178361146105fe578063af198b9714610625578063c3f909d414610655578063caf70c4a146106a757600080fd5b80638da5cb5b11610114578063a21a23e4116100f9578063a21a23e4146105c0578063a47c7696146105c8578063a4c0ed36146105eb57600080fd5b80638da5cb5b1461059c5780639f87fad7146105ad57600080fd5b80636f64f03f1461055b5780637341c10c1461056e57806379ba509714610581578063823597401461058957600080fd5b8063356dac71116101d85780635fbbc0d2116101a757806366316d8d1161018c57806366316d8d14610501578063689c45171461051457806369bcdb7d1461053b57600080fd5b80635fbbc0d2146103f357806364d51a2a146104f957600080fd5b8063356dac71146103a757806340d6bb82146103af5780634cb48a54146103cd5780635d3b1d30146103e057600080fd5b806308821d581161022f57806315c48b841161021457806315c48b841461030e578063181f5a77146103295780631b6b6d231461036857600080fd5b806308821d58146102cf57806312b58349146102e257600080fd5b80620122911461026057806302bcc5b61461028057806304c357cb1461029557806306bfa637146102a8575b600080fd5b610268610729565b604051610277939291906152a6565b60405180910390f35b61029361028e3660046150f2565b6107a5565b005b6102936102a336600461510d565b610837565b60055467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610277565b6102936102dd366004614e03565b6109eb565b6005546801000000000000000090046bffffffffffffffffffffffff165b604051908152602001610277565b61031660c881565b60405161ffff9091168152602001610277565b604080518082018252601681527f565246436f6f7264696e61746f72563220312e302e3000000000000000000000602082015290516102779190615251565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b600a54610300565b6103b86101f481565b60405163ffffffff9091168152602001610277565b6102936103db366004614f9c565b610bb0565b6103006103ee366004614e76565b610fa7565b600c546040805163ffffffff80841682526401000000008404811660208301526801000000000000000084048116928201929092526c010000000000000000000000008304821660608201527001000000000000000000000000000000008304909116608082015262ffffff740100000000000000000000000000000000000000008304811660a0830152770100000000000000000000000000000000000000000000008304811660c08301527a0100000000000000000000000000000000000000000000000000008304811660e08301527d01000000000000000000000000000000000000000000000000000000000090920490911661010082015261012001610277565b610316606481565b61029361050f366004614dbb565b611385565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b6103006105493660046150d9565b60009081526009602052604090205490565b610293610569366004614d00565b6115d4565b61029361057c36600461510d565b611704565b610293611951565b6102936105973660046150f2565b611a1a565b6000546001600160a01b031661038f565b6102936105bb36600461510d565b611be0565b6102b661201f565b6105db6105d63660046150f2565b612202565b6040516102779493929190615444565b6102936105f9366004614d34565b612325565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b610638610633366004614ed4565b61257c565b6040516bffffffffffffffffffffffff9091168152602001610277565b600b546040805161ffff8316815263ffffffff6201000084048116602083015267010000000000000084048116928201929092526b010000000000000000000000909204166060820152608001610277565b6103006106b5366004614e1f565b612a16565b6103b86106c83660046150f2565b612a46565b6102936106db36600461510d565b612c3b565b6102936106ee366004614ce5565b612d75565b6107066107013660046150f2565b612fb2565b6040519015158152602001610277565b610293610724366004614ce5565b6131d5565b600b546007805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff1693919283919083018282801561079357602002820191906000526020600020905b81548152602001906001019080831161077f575b50505050509050925092509250909192565b6107ad6131e6565b67ffffffffffffffff81166000908152600360205260409020546001600160a01b0316610806576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020546108349082906001600160a01b0316613242565b50565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680610893576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b038216146108e5576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024015b60405180910390fd5b600b546601000000000000900460ff161561092c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600360205260409020600101546001600160a01b038481169116146109e55767ffffffffffffffff841660008181526003602090815260409182902060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0388169081179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91015b60405180910390a25b50505050565b6109f36131e6565b604080518082018252600091610a22919084906002908390839080828437600092019190915250612a16915050565b6000818152600660205260409020549091506001600160a01b031680610a77576040517f77f5b84c000000000000000000000000000000000000000000000000000000008152600481018390526024016108dc565b600082815260066020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555b600754811015610b67578260078281548110610aca57610aca6156f1565b90600052602060002001541415610b55576007805460009190610aef906001906155ab565b81548110610aff57610aff6156f1565b906000526020600020015490508060078381548110610b2057610b206156f1565b6000918252602090912001556007805480610b3d57610b3d6156c2565b60019003818190600052602060002001600090559055505b80610b5f816155ef565b915050610aac565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610ba391815260200190565b60405180910390a2505050565b610bb86131e6565b60c861ffff87161115610c0b576040517fa738697600000000000000000000000000000000000000000000000000000000815261ffff871660048201819052602482015260c860448201526064016108dc565b60008213610c48576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018390526024016108dc565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000001690971762010000909502949094177fffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff166701000000000000009092027fffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffff16919091176b010000000000000000000000909302929092179093558651600c80549489015189890151938a0151978a0151968a015160c08b015160e08c01516101008d01519588167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009099169890981764010000000093881693909302929092177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff1668010000000000000000958716959095027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16949094176c0100000000000000000000000098861698909802979097177fffffffffffffffffff00000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000096909416959095027fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff16929092177401000000000000000000000000000000000000000062ffffff92831602177fffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffff1677010000000000000000000000000000000000000000000000958216959095027fffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffff16949094177a01000000000000000000000000000000000000000000000000000092851692909202919091177cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d0100000000000000000000000000000000000000000000000000000000009390911692909202919091178155600a84905590517fc21e3bd2e0b339d2848f0dd956947a88966c242c0c0c582a33137a5c1ceb5cb291610f97918991899189918991899190615305565b60405180910390a1505050505050565b600b546000906601000000000000900460ff1615610ff1576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff85166000908152600360205260409020546001600160a01b031661104a576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260026020908152604080832067ffffffffffffffff808a16855292529091205416806110ba576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff871660048201523360248201526044016108dc565b600b5461ffff90811690861610806110d6575060c861ffff8616115b1561112657600b546040517fa738697600000000000000000000000000000000000000000000000000000000815261ffff8088166004830152909116602482015260c860448201526064016108dc565b600b5463ffffffff620100009091048116908516111561118d57600b546040517ff5d7e01e00000000000000000000000000000000000000000000000000000000815263ffffffff80871660048301526201000090920490911660248201526044016108dc565b6101f463ffffffff841611156111df576040517f47386bec00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201526101f460248201526044016108dc565b60006111ec826001615507565b6040805160208082018c9052338284015267ffffffffffffffff808c16606084015284166080808401919091528351808403909101815260a08301845280519082012060c083018d905260e080840182905284518085039091018152610100909301909352815191012091925081611262613667565b60408051602081019390935282015267ffffffffffffffff8a16606082015263ffffffff8089166080830152871660a08201523360c082015260e00160408051808303601f19018152828252805160209182012060008681526009835283902055848352820183905261ffff8a169082015263ffffffff808916606083015287166080820152339067ffffffffffffffff8b16908c907f63373d1c4696214b898952999c9aaec57dac1ee2723cec59bea6888f489a97729060a00160405180910390a45033600090815260026020908152604080832067ffffffffffffffff808d16855292529091208054919093167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790915591505095945050505050565b600b546601000000000000900460ff16156113cc576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600860205260409020546bffffffffffffffffffffffff80831691161015611426576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260086020526040812080548392906114539084906bffffffffffffffffffffffff166155c2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080600560088282829054906101000a90046bffffffffffffffffffffffff166114aa91906155c2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb83836040518363ffffffff1660e01b81526004016115489291906001600160a01b039290921682526bffffffffffffffffffffffff16602082015260400190565b602060405180830381600087803b15801561156257600080fd5b505af1158015611576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159a9190614e3b565b6115d0576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b6115dc6131e6565b60408051808201825260009161160b919084906002908390839080828437600092019190915250612a16915050565b6000818152600660205260409020549091506001600160a01b031615611660576040517f4a0b8fa7000000000000000000000000000000000000000000000000000000008152600481018290526024016108dc565b600081815260066020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0388169081179091556007805460018101825594527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610ba3565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680611760576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b038216146117ad576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff16156117f4576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600360205260409020600201546064141561184b576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600090815260026020908152604080832067ffffffffffffffff80891685529252909120541615611885576109e5565b6001600160a01b038316600081815260026020818152604080842067ffffffffffffffff8a1680865290835281852080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001908117909155600384528286209094018054948501815585529382902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001685179055905192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091016109dc565b6001546001600160a01b031633146119ab5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108dc565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600b546601000000000000900460ff1615611a61576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020546001600160a01b0316611aba576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020600101546001600160a01b03163314611b425767ffffffffffffffff8116600090815260036020526040908190206001015490517fd084e9750000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016108dc565b67ffffffffffffffff81166000818152600360209081526040918290208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001909301805490931690925583516001600160a01b03909116808252928101919091529092917f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0910160405180910390a25050565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680611c3c576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614611c89576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff1615611cd0576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cd984612fb2565b15611d10576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600090815260026020908152604080832067ffffffffffffffff808916855292529091205416611d91576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526001600160a01b03841660248201526044016108dc565b67ffffffffffffffff8416600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611dff57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611de1575b50505050509050600060018251611e1691906155ab565b905060005b8251811015611f8e57856001600160a01b0316838281518110611e4057611e406156f1565b60200260200101516001600160a01b03161415611f7c576000838381518110611e6b57611e6b6156f1565b6020026020010151905080600360008a67ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018381548110611eb157611eb16156f1565b600091825260208083209190910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03949094169390931790925567ffffffffffffffff8a168152600390915260409020600201805480611f1e57611f1e6156c2565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f8e565b80611f86816155ef565b915050611e1b565b506001600160a01b038516600081815260026020908152604080832067ffffffffffffffff8b168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a2505050505050565b600b546000906601000000000000900460ff1615612069576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805467ffffffffffffffff1690600061208383615628565b82546101009290920a67ffffffffffffffff8181021990931691831602179091556005541690506000806040519080825280602002602001820160405280156120d6578160200160208202803683370190505b506040805180820182526000808252602080830182815267ffffffffffffffff888116808552600484528685209551865493516bffffffffffffffffffffffff9091167fffffffffffffffffffffffff0000000000000000000000000000000000000000948516176c01000000000000000000000000919093160291909117909455845160608101865233815280830184815281870188815295855260038452959093208351815483166001600160a01b03918216178255955160018201805490931696169590951790559151805194955090936121ba9260028501920190614a3f565b505060405133815267ffffffffffffffff841691507f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a250905090565b67ffffffffffffffff8116600090815260036020526040812054819081906060906001600160a01b0316612262576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff80861660009081526004602090815260408083205460038352928190208054600290910180548351818602810186019094528084526bffffffffffffffffffffffff8616966c01000000000000000000000000909604909516946001600160a01b0390921693909291839183018282801561230f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122f1575b5050505050905093509350935093509193509193565b600b546601000000000000900460ff161561236c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146123ce576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612408576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612416828401846150f2565b67ffffffffffffffff81166000908152600360205260409020549091506001600160a01b0316612472576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260046020526040812080546bffffffffffffffffffffffff16918691906124a98385615533565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555084600560088282829054906101000a90046bffffffffffffffffffffffff166125009190615533565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f882878461256791906154ef565b6040805192835260208301919091520161200f565b600b546000906601000000000000900460ff16156125c6576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005a905060008060006125da8787613700565b9250925092506000866060015163ffffffff1667ffffffffffffffff81111561260557612605615720565b60405190808252806020026020018201604052801561262e578160200160208202803683370190505b50905060005b876060015163ffffffff168110156126a25760408051602081018590529081018290526060016040516020818303038152906040528051906020012060001c828281518110612685576126856156f1565b60209081029190910101528061269a816155ef565b915050612634565b506000838152600960205260408082208290555181907f1fe543e300000000000000000000000000000000000000000000000000000000906126ea90879086906024016153f6565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252600b80547fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff166601000000000000179055908a015160808b015191925060009161279a9163ffffffff169084613a0e565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff1690556020808c01805167ffffffffffffffff9081166000908152600490935260408084205492518216845290922080549394506c01000000000000000000000000918290048316936001939192600c9261281e928692900416615507565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006128758a600b600001600b9054906101000a900463ffffffff1663ffffffff1661286f85612a46565b3a613a5c565b6020808e015167ffffffffffffffff166000908152600490915260409020549091506bffffffffffffffffffffffff808316911610156128e1576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808d015167ffffffffffffffff166000908152600490915260408120805483929061291d9084906bffffffffffffffffffffffff166155c2565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008b8152600660209081526040808320546001600160a01b03168352600890915281208054859450909261297991859116615533565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550877f7dffc5ae5ee4e2e4df1651cf6ad329a73cebdb728f37ea0187b9b17e036756e48883866040516129fc939291909283526bffffffffffffffffffffffff9190911660208301521515604082015260600190565b60405180910390a299505050505050505050505b92915050565b600081604051602001612a299190615243565b604051602081830303815290604052805190602001209050919050565b6040805161012081018252600c5463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015262ffffff740100000000000000000000000000000000000000008304811660a08301819052770100000000000000000000000000000000000000000000008404821660c08401527a0100000000000000000000000000000000000000000000000000008404821660e08401527d0100000000000000000000000000000000000000000000000000000000009093041661010082015260009167ffffffffffffffff841611612b64575192915050565b8267ffffffffffffffff168160a0015162ffffff16108015612b9957508060c0015162ffffff168367ffffffffffffffff1611155b15612ba8576020015192915050565b8267ffffffffffffffff168160c0015162ffffff16108015612bdd57508060e0015162ffffff168367ffffffffffffffff1611155b15612bec576040015192915050565b8267ffffffffffffffff168160e0015162ffffff16108015612c22575080610100015162ffffff168367ffffffffffffffff1611155b15612c31576060015192915050565b6080015192915050565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680612c97576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614612ce4576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff1615612d2b576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d3484612fb2565b15612d6b576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109e58484613242565b612d7d6131e6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015612df857600080fd5b505afa158015612e0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e309190614e5d565b6005549091506801000000000000000090046bffffffffffffffffffffffff1681811115612e94576040517fa99da30200000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016108dc565b81811015612fad576000612ea882846155ab565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb90604401602060405180830381600087803b158015612f3057600080fd5b505af1158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190614e3b565b50604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a1505b505050565b67ffffffffffffffff81166000908152600360209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561304757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613029575b505050505081525050905060005b8160400151518110156131cb5760005b6007548110156131b857600061318160078381548110613087576130876156f1565b9060005260206000200154856040015185815181106130a8576130a86156f1565b60200260200101518860026000896040015189815181106130cb576130cb6156f1565b6020908102919091018101516001600160a01b03168252818101929092526040908101600090812067ffffffffffffffff808f16835293522054166040805160208082018790526001600160a01b03959095168183015267ffffffffffffffff9384166060820152919092166080808301919091528251808303909101815260a08201835280519084012060c082019490945260e080820185905282518083039091018152610100909101909152805191012091565b50600081815260096020526040902054909150156131a55750600195945050505050565b50806131b0816155ef565b915050613065565b50806131c3816155ef565b915050613055565b5060009392505050565b6131dd6131e6565b61083481613b7c565b6000546001600160a01b031633146132405760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108dc565b565b600b546601000000000000900460ff1615613289576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160608101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181529295939486019383018282801561331a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116132fc575b5050509190925250505067ffffffffffffffff80851660009081526004602090815260408083208151808301909252546bffffffffffffffffffffffff81168083526c01000000000000000000000000909104909416918101919091529293505b8360400151518110156134145760026000856040015183815181106133a2576133a26156f1565b6020908102919091018101516001600160a01b03168252818101929092526040908101600090812067ffffffffffffffff8a168252909252902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690558061340c816155ef565b91505061337b565b5067ffffffffffffffff8516600090815260036020526040812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825560018201805490911690559061346f6002830182614abc565b505067ffffffffffffffff8516600090815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600580548291906008906134df9084906801000000000000000090046bffffffffffffffffffffffff166155c2565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb85836bffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161357d9291906001600160a01b03929092168252602082015260400190565b602060405180830381600087803b15801561359757600080fd5b505af11580156135ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135cf9190614e3b565b613605576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b03861681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8716917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815910160405180910390a25050505050565b60004661a4b181148061367c575062066eed81145b156136f95760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136bb57600080fd5b505afa1580156136cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136f39190614e5d565b91505090565b4391505090565b60008060006137128560000151612a16565b6000818152600660205260409020549093506001600160a01b031680613767576040517f77f5b84c000000000000000000000000000000000000000000000000000000008152600481018590526024016108dc565b6080860151604051613786918691602001918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526009909352912054909350806137e5576040517f3688124a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85516020808801516040808a015160608b015160808c01519251613851968b96909594910195865267ffffffffffffffff948516602087015292909316604085015263ffffffff90811660608501529190911660808301526001600160a01b031660a082015260c00190565b60405160208183030381529060405280519060200120811461389f576040517fd529142c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006138ae8760000151613c3e565b9050806139ba5786516040517fe9413d3800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b15801561393a57600080fd5b505afa15801561394e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139729190614e5d565b9050806139ba5786516040517f175dadad00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108dc565b60008860800151826040516020016139dc929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c9050613a018982613d52565b9450505050509250925092565b60005a611388811015613a2057600080fd5b611388810390508460408204820311613a3857600080fd5b50823b613a4457600080fd5b60008083516020850160008789f190505b9392505050565b600080613a67613dbd565b905060008113613aa6576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018290526024016108dc565b6000613ab0613ec4565b9050600082825a613ac18b8b6154ef565b613acb91906155ab565b613ad5908861556e565b613adf91906154ef565b613af190670de0b6b3a764000061556e565b613afb919061555a565b90506000613b1463ffffffff881664e8d4a5100061556e565b9050613b2c816b033b2e3c9fd0803ce80000006155ab565b821115613b65576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613b6f81836154ef565b9998505050505050505050565b6001600160a01b038116331415613bd55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108dc565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b1811480613c53575062066eed81145b80613c60575062066eee81145b15613d42576101008367ffffffffffffffff16613c7b613667565b613c8591906155ab565b1180613ca25750613c94613667565b8367ffffffffffffffff1610155b15613cb05750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b158015613d0a57600080fd5b505afa158015613d1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a559190614e5d565b505067ffffffffffffffff164090565b6000613d868360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613f20565b60038360200151604051602001613d9e9291906153e2565b60408051601f1981840301815291905280516020909101209392505050565b600b54604080517ffeaf968c0000000000000000000000000000000000000000000000000000000081529051600092670100000000000000900463ffffffff169182151591849182917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b158015613e5657600080fd5b505afa158015613e6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e8e9190615137565b509450909250849150508015613eb25750613ea982426155ab565b8463ffffffff16105b15613ebc5750600a545b949350505050565b60004661a4b1811480613ed9575062066eed81145b15613f1857606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136bb57600080fd5b600091505090565b613f298961415b565b613f755760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e20637572766500000000000060448201526064016108dc565b613f7e8861415b565b613fca5760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e206375727665000000000000000000000060448201526064016108dc565b613fd38361415b565b61401f5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e20637572766500000060448201526064016108dc565b6140288261415b565b6140745760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e2063757276650000000060448201526064016108dc565b614080878a8887614234565b6140cc5760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e6573730000000000000060448201526064016108dc565b60006140d88a87614385565b905060006140eb898b878b8689896143e9565b905060006140fc838d8d8a86614515565b9050808a1461414d5760405162461bcd60e51b815260206004820152600d60248201527f696e76616c69642070726f6f660000000000000000000000000000000000000060448201526064016108dc565b505050505050505050505050565b80516000906401000003d019116141b45760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e617465000000000000000000000000000060448201526064016108dc565b60208201516401000003d0191161420d5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e617465000000000000000000000000000060448201526064016108dc565b60208201516401000003d01990800961422d8360005b6020020151614555565b1492915050565b60006001600160a01b03821661428c5760405162461bcd60e51b815260206004820152600b60248201527f626164207769746e65737300000000000000000000000000000000000000000060448201526064016108dc565b6020840151600090600116156142a357601c6142a6565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641418587600060200201510986517ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa15801561435d573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b61438d614ada565b6143ba600184846040516020016143a693929190615222565b604051602081830303815290604052614579565b90505b6143c68161415b565b612a105780516040805160208101929092526143e291016143a6565b90506143bd565b6143f1614ada565b825186516401000003d01990819006910614156144505760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e6374000060448201526064016108dc565b61445b8789886145c8565b6144a75760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c65640000000000000000000060448201526064016108dc565b6144b28486856145c8565b6144fe5760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c656400000000000000000060448201526064016108dc565b614509868484614710565b98975050505050505050565b600060028686868587604051602001614533969594939291906151b0565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614581614ada565b61458a826147d7565b815261459f61459a826000614223565b614812565b6020820181905260029006600114156145c3576020810180516401000003d0190390525b919050565b6000826146175760405162461bcd60e51b815260206004820152600b60248201527f7a65726f207363616c617200000000000000000000000000000000000000000060448201526064016108dc565b8351602085015160009061462d90600290615650565b1561463957601c61463c565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641418387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa1580156146bc573d6000803e3d6000fd5b5050506020604051035190506000866040516020016146db919061519e565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614718614ada565b83516020808601518551918601516000938493849361473993909190614832565b919450925090506401000003d0198582096001146147995760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a0000000000000060448201526064016108dc565b60405180604001604052806401000003d019806147b8576147b8615693565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d01981106145c3576040805160208082019390935281518082038401815290820190915280519101206147df565b6000612a1082600261482b6401000003d01960016154ef565b901c614912565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614872838385856149d2565b909850905061488388828e886149f6565b909850905061489488828c876149f6565b909850905060006148a78d878b856149f6565b90985090506148b8888286866149d2565b90985090506148c988828e896149f6565b90985090508181146148fe576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614902565b8196505b5050505050509450945094915050565b60008061491d614af8565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a082015261494f614b16565b60208160c08460057ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9250826149c85760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c75726521000000000000000000000000000060448201526064016108dc565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614aac579160200282015b82811115614aac57825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190614a5f565b50614ab8929150614b34565b5090565b50805460008255906000526020600020908101906108349190614b34565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614ab85760008155600101614b35565b80356001600160a01b03811681146145c357600080fd5b8060408101831015612a1057600080fd5b600082601f830112614b8257600080fd5b6040516040810181811067ffffffffffffffff82111715614ba557614ba5615720565b8060405250808385604086011115614bbc57600080fd5b60005b6002811015614bde578135835260209283019290910190600101614bbf565b509195945050505050565b600060a08284031215614bfb57600080fd5b60405160a0810181811067ffffffffffffffff82111715614c1e57614c1e615720565b604052905080614c2d83614cb3565b8152614c3b60208401614cb3565b6020820152614c4c60408401614c9f565b6040820152614c5d60608401614c9f565b6060820152614c6e60808401614b49565b60808201525092915050565b803561ffff811681146145c357600080fd5b803562ffffff811681146145c357600080fd5b803563ffffffff811681146145c357600080fd5b803567ffffffffffffffff811681146145c357600080fd5b805169ffffffffffffffffffff811681146145c357600080fd5b600060208284031215614cf757600080fd5b613a5582614b49565b60008060608385031215614d1357600080fd5b614d1c83614b49565b9150614d2b8460208501614b60565b90509250929050565b60008060008060608587031215614d4a57600080fd5b614d5385614b49565b935060208501359250604085013567ffffffffffffffff80821115614d7757600080fd5b818701915087601f830112614d8b57600080fd5b813581811115614d9a57600080fd5b886020828501011115614dac57600080fd5b95989497505060200194505050565b60008060408385031215614dce57600080fd5b614dd783614b49565b915060208301356bffffffffffffffffffffffff81168114614df857600080fd5b809150509250929050565b600060408284031215614e1557600080fd5b613a558383614b60565b600060408284031215614e3157600080fd5b613a558383614b71565b600060208284031215614e4d57600080fd5b81518015158114613a5557600080fd5b600060208284031215614e6f57600080fd5b5051919050565b600080600080600060a08688031215614e8e57600080fd5b85359450614e9e60208701614cb3565b9350614eac60408701614c7a565b9250614eba60608701614c9f565b9150614ec860808701614c9f565b90509295509295909350565b600080828403610240811215614ee957600080fd5b6101a080821215614ef957600080fd5b614f016154c5565b9150614f0d8686614b71565b8252614f1c8660408701614b71565b60208301526080850135604083015260a0850135606083015260c08501356080830152614f4b60e08601614b49565b60a0830152610100614f5f87828801614b71565b60c0840152614f72876101408801614b71565b60e08401526101808601358184015250819350614f9186828701614be9565b925050509250929050565b6000806000806000808688036101c0811215614fb757600080fd5b614fc088614c7a565b9650614fce60208901614c9f565b9550614fdc60408901614c9f565b9450614fea60608901614c9f565b935060808801359250610120807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608301121561502557600080fd5b61502d6154c5565b915061503b60a08a01614c9f565b825261504960c08a01614c9f565b602083015261505a60e08a01614c9f565b604083015261010061506d818b01614c9f565b606084015261507d828b01614c9f565b608084015261508f6101408b01614c8c565b60a08401526150a16101608b01614c8c565b60c08401526150b36101808b01614c8c565b60e08401526150c56101a08b01614c8c565b818401525050809150509295509295509295565b6000602082840312156150eb57600080fd5b5035919050565b60006020828403121561510457600080fd5b613a5582614cb3565b6000806040838503121561512057600080fd5b61512983614cb3565b9150614d2b60208401614b49565b600080600080600060a0868803121561514f57600080fd5b61515886614ccb565b9450602086015193506040860151925060608601519150614ec860808701614ccb565b8060005b60028110156109e557815184526020938401939091019060010161517f565b6151a8818361517b565b604001919050565b8681526151c0602082018761517b565b6151cd606082018661517b565b6151da60a082018561517b565b6151e760e082018461517b565b60609190911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166101208201526101340195945050505050565b838152615232602082018461517b565b606081019190915260800192915050565b60408101612a10828461517b565b600060208083528351808285015260005b8181101561527e57858101830151858201604001528201615262565b81811115615290576000604083870101525b50601f01601f1916929092016040019392505050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b818110156152f7578451835293830193918301916001016152db565b509098975050505050505050565b60006101c08201905061ffff8816825263ffffffff808816602084015280871660408401528086166060840152846080840152835481811660a085015261535960c08501838360201c1663ffffffff169052565b61537060e08501838360401c1663ffffffff169052565b6153886101008501838360601c1663ffffffff169052565b6153a06101208501838360801c1663ffffffff169052565b62ffffff60a082901c811661014086015260b882901c811661016086015260d082901c1661018085015260e81c6101a090930192909252979650505050505050565b82815260608101613a55602083018461517b565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156154375784518352938301939183019160010161541b565b5090979650505050505050565b6000608082016bffffffffffffffffffffffff87168352602067ffffffffffffffff8716818501526001600160a01b0380871660408601526080606086015282865180855260a087019150838801945060005b818110156154b5578551841683529484019491840191600101615497565b50909a9950505050505050505050565b604051610120810167ffffffffffffffff811182821017156154e9576154e9615720565b60405290565b6000821982111561550257615502615664565b500190565b600067ffffffffffffffff80831681851680830382111561552a5761552a615664565b01949350505050565b60006bffffffffffffffffffffffff80831681851680830382111561552a5761552a615664565b60008261556957615569615693565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155a6576155a6615664565b500290565b6000828210156155bd576155bd615664565b500390565b60006bffffffffffffffffffffffff838116908316818110156155e7576155e7615664565b039392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561562157615621615664565b5060010190565b600067ffffffffffffffff8083168181141561564657615646615664565b6001019392505050565b60008261565f5761565f615693565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", + Bin: "0x60e06040523480156200001157600080fd5b50604051620059bc380380620059bc8339810160408190526200003491620001b1565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000e8565b5050506001600160601b0319606093841b811660805290831b811660a052911b1660c052620001fb565b6001600160a01b038116331415620001435760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001ac57600080fd5b919050565b600080600060608486031215620001c757600080fd5b620001d28462000194565b9250620001e26020850162000194565b9150620001f26040850162000194565b90509250925092565b60805160601c60a05160601c60c05160601c615757620002656000396000818161051901526138e70152600081816106030152613e0c01526000818161036d015281816114da0152818161237701528181612dae01528181612eea015261350f01526157576000f3fe608060405234801561001057600080fd5b506004361061025b5760003560e01c80636f64f03f11610145578063ad178361116100bd578063d2f9f9a71161008c578063e72f6e3011610071578063e72f6e30146106e0578063e82ad7d4146106f3578063f2fde38b1461071657600080fd5b8063d2f9f9a7146106ba578063d7ae1d30146106cd57600080fd5b8063ad178361146105fe578063af198b9714610625578063c3f909d414610655578063caf70c4a146106a757600080fd5b80638da5cb5b11610114578063a21a23e4116100f9578063a21a23e4146105c0578063a47c7696146105c8578063a4c0ed36146105eb57600080fd5b80638da5cb5b1461059c5780639f87fad7146105ad57600080fd5b80636f64f03f1461055b5780637341c10c1461056e57806379ba509714610581578063823597401461058957600080fd5b8063356dac71116101d85780635fbbc0d2116101a757806366316d8d1161018c57806366316d8d14610501578063689c45171461051457806369bcdb7d1461053b57600080fd5b80635fbbc0d2146103f357806364d51a2a146104f957600080fd5b8063356dac71146103a757806340d6bb82146103af5780634cb48a54146103cd5780635d3b1d30146103e057600080fd5b806308821d581161022f57806315c48b841161021457806315c48b841461030e578063181f5a77146103295780631b6b6d231461036857600080fd5b806308821d58146102cf57806312b58349146102e257600080fd5b80620122911461026057806302bcc5b61461028057806304c357cb1461029557806306bfa637146102a8575b600080fd5b610268610729565b604051610277939291906152a1565b60405180910390f35b61029361028e3660046150ed565b6107a5565b005b6102936102a3366004615108565b610837565b60055467ffffffffffffffff165b60405167ffffffffffffffff9091168152602001610277565b6102936102dd366004614dfe565b6109eb565b6005546801000000000000000090046bffffffffffffffffffffffff165b604051908152602001610277565b61031660c881565b60405161ffff9091168152602001610277565b604080518082018252601681527f565246436f6f7264696e61746f72563220312e302e300000000000000000000060208201529051610277919061524c565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610277565b600a54610300565b6103b86101f481565b60405163ffffffff9091168152602001610277565b6102936103db366004614f97565b610bb0565b6103006103ee366004614e71565b610fa7565b600c546040805163ffffffff80841682526401000000008404811660208301526801000000000000000084048116928201929092526c010000000000000000000000008304821660608201527001000000000000000000000000000000008304909116608082015262ffffff740100000000000000000000000000000000000000008304811660a0830152770100000000000000000000000000000000000000000000008304811660c08301527a0100000000000000000000000000000000000000000000000000008304811660e08301527d01000000000000000000000000000000000000000000000000000000000090920490911661010082015261012001610277565b610316606481565b61029361050f366004614db6565b611385565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b6103006105493660046150d4565b60009081526009602052604090205490565b610293610569366004614cfb565b6115d4565b61029361057c366004615108565b611704565b610293611951565b6102936105973660046150ed565b611a1a565b6000546001600160a01b031661038f565b6102936105bb366004615108565b611be0565b6102b661201f565b6105db6105d63660046150ed565b612202565b604051610277949392919061543f565b6102936105f9366004614d2f565b612325565b61038f7f000000000000000000000000000000000000000000000000000000000000000081565b610638610633366004614ecf565b61257c565b6040516bffffffffffffffffffffffff9091168152602001610277565b600b546040805161ffff8316815263ffffffff6201000084048116602083015267010000000000000084048116928201929092526b010000000000000000000000909204166060820152608001610277565b6103006106b5366004614e1a565b612a16565b6103b86106c83660046150ed565b612a46565b6102936106db366004615108565b612c3b565b6102936106ee366004614ce0565b612d75565b6107066107013660046150ed565b612fb2565b6040519015158152602001610277565b610293610724366004614ce0565b6131d5565b600b546007805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff1693919283919083018282801561079357602002820191906000526020600020905b81548152602001906001019080831161077f575b50505050509050925092509250909192565b6107ad6131e6565b67ffffffffffffffff81166000908152600360205260409020546001600160a01b0316610806576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020546108349082906001600160a01b0316613242565b50565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680610893576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b038216146108e5576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024015b60405180910390fd5b600b546601000000000000900460ff161561092c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600360205260409020600101546001600160a01b038481169116146109e55767ffffffffffffffff841660008181526003602090815260409182902060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0388169081179091558251338152918201527f69436ea6df009049404f564eff6622cd00522b0bd6a89efd9e52a355c4a879be91015b60405180910390a25b50505050565b6109f36131e6565b604080518082018252600091610a22919084906002908390839080828437600092019190915250612a16915050565b6000818152600660205260409020549091506001600160a01b031680610a77576040517f77f5b84c000000000000000000000000000000000000000000000000000000008152600481018390526024016108dc565b600082815260066020526040812080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555b600754811015610b67578260078281548110610aca57610aca6156ec565b90600052602060002001541415610b55576007805460009190610aef906001906155a6565b81548110610aff57610aff6156ec565b906000526020600020015490508060078381548110610b2057610b206156ec565b6000918252602090912001556007805480610b3d57610b3d6156bd565b60019003818190600052602060002001600090559055505b80610b5f816155ea565b915050610aac565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610ba391815260200190565b60405180910390a2505050565b610bb86131e6565b60c861ffff87161115610c0b576040517fa738697600000000000000000000000000000000000000000000000000000000815261ffff871660048201819052602482015260c860448201526064016108dc565b60008213610c48576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018390526024016108dc565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600b80547fffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000001690971762010000909502949094177fffffffffffffffffffffffffffffffffff000000000000000000ffffffffffff166701000000000000009092027fffffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffff16919091176b010000000000000000000000909302929092179093558651600c80549489015189890151938a0151978a0151968a015160c08b015160e08c01516101008d01519588167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009099169890981764010000000093881693909302929092177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff1668010000000000000000958716959095027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16949094176c0100000000000000000000000098861698909802979097177fffffffffffffffffff00000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000096909416959095027fffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffff16929092177401000000000000000000000000000000000000000062ffffff92831602177fffffff000000000000ffffffffffffffffffffffffffffffffffffffffffffff1677010000000000000000000000000000000000000000000000958216959095027fffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffff16949094177a01000000000000000000000000000000000000000000000000000092851692909202919091177cffffffffffffffffffffffffffffffffffffffffffffffffffffffffff167d0100000000000000000000000000000000000000000000000000000000009390911692909202919091178155600a84905590517fc21e3bd2e0b339d2848f0dd956947a88966c242c0c0c582a33137a5c1ceb5cb291610f97918991899189918991899190615300565b60405180910390a1505050505050565b600b546000906601000000000000900460ff1615610ff1576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff85166000908152600360205260409020546001600160a01b031661104a576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260026020908152604080832067ffffffffffffffff808a16855292529091205416806110ba576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff871660048201523360248201526044016108dc565b600b5461ffff90811690861610806110d6575060c861ffff8616115b1561112657600b546040517fa738697600000000000000000000000000000000000000000000000000000000815261ffff8088166004830152909116602482015260c860448201526064016108dc565b600b5463ffffffff620100009091048116908516111561118d57600b546040517ff5d7e01e00000000000000000000000000000000000000000000000000000000815263ffffffff80871660048301526201000090920490911660248201526044016108dc565b6101f463ffffffff841611156111df576040517f47386bec00000000000000000000000000000000000000000000000000000000815263ffffffff841660048201526101f460248201526044016108dc565b60006111ec826001615502565b6040805160208082018c9052338284015267ffffffffffffffff808c16606084015284166080808401919091528351808403909101815260a08301845280519082012060c083018d905260e080840182905284518085039091018152610100909301909352815191012091925081611262613667565b60408051602081019390935282015267ffffffffffffffff8a16606082015263ffffffff8089166080830152871660a08201523360c082015260e00160408051808303601f19018152828252805160209182012060008681526009835283902055848352820183905261ffff8a169082015263ffffffff808916606083015287166080820152339067ffffffffffffffff8b16908c907f63373d1c4696214b898952999c9aaec57dac1ee2723cec59bea6888f489a97729060a00160405180910390a45033600090815260026020908152604080832067ffffffffffffffff808d16855292529091208054919093167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009091161790915591505095945050505050565b600b546601000000000000900460ff16156113cc576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336000908152600860205260409020546bffffffffffffffffffffffff80831691161015611426576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600090815260086020526040812080548392906114539084906bffffffffffffffffffffffff166155bd565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555080600560088282829054906101000a90046bffffffffffffffffffffffff166114aa91906155bd565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb83836040518363ffffffff1660e01b81526004016115489291906001600160a01b039290921682526bffffffffffffffffffffffff16602082015260400190565b602060405180830381600087803b15801561156257600080fd5b505af1158015611576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061159a9190614e36565b6115d0576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050565b6115dc6131e6565b60408051808201825260009161160b919084906002908390839080828437600092019190915250612a16915050565b6000818152600660205260409020549091506001600160a01b031615611660576040517f4a0b8fa7000000000000000000000000000000000000000000000000000000008152600481018290526024016108dc565b600081815260066020908152604080832080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0388169081179091556007805460018101825594527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610ba3565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680611760576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b038216146117ad576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff16156117f4576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff84166000908152600360205260409020600201546064141561184b576040517f05a48e0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600090815260026020908152604080832067ffffffffffffffff80891685529252909120541615611885576109e5565b6001600160a01b038316600081815260026020818152604080842067ffffffffffffffff8a1680865290835281852080547fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000166001908117909155600384528286209094018054948501815585529382902090920180547fffffffffffffffffffffffff00000000000000000000000000000000000000001685179055905192835290917f43dc749a04ac8fb825cbd514f7c0e13f13bc6f2ee66043b76629d51776cff8e091016109dc565b6001546001600160a01b031633146119ab5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016108dc565b60008054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600b546601000000000000900460ff1615611a61576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020546001600160a01b0316611aba576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff81166000908152600360205260409020600101546001600160a01b03163314611b425767ffffffffffffffff8116600090815260036020526040908190206001015490517fd084e9750000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201526024016108dc565b67ffffffffffffffff81166000818152600360209081526040918290208054337fffffffffffffffffffffffff0000000000000000000000000000000000000000808316821784556001909301805490931690925583516001600160a01b03909116808252928101919091529092917f6f1dc65165ffffedfd8e507b4a0f1fcfdada045ed11f6c26ba27cedfe87802f0910160405180910390a25050565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680611c3c576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614611c89576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff1615611cd0576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611cd984612fb2565b15611d10576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038316600090815260026020908152604080832067ffffffffffffffff808916855292529091205416611d91576040517ff0019fe600000000000000000000000000000000000000000000000000000000815267ffffffffffffffff851660048201526001600160a01b03841660248201526044016108dc565b67ffffffffffffffff8416600090815260036020908152604080832060020180548251818502810185019093528083529192909190830182828015611dff57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611de1575b50505050509050600060018251611e1691906155a6565b905060005b8251811015611f8e57856001600160a01b0316838281518110611e4057611e406156ec565b60200260200101516001600160a01b03161415611f7c576000838381518110611e6b57611e6b6156ec565b6020026020010151905080600360008a67ffffffffffffffff1667ffffffffffffffff1681526020019081526020016000206002018381548110611eb157611eb16156ec565b600091825260208083209190910180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03949094169390931790925567ffffffffffffffff8a168152600390915260409020600201805480611f1e57611f1e6156bd565b60008281526020902081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905501905550611f8e565b80611f86816155ea565b915050611e1b565b506001600160a01b038516600081815260026020908152604080832067ffffffffffffffff8b168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690555192835290917f182bff9831466789164ca77075fffd84916d35a8180ba73c27e45634549b445b91015b60405180910390a2505050505050565b600b546000906601000000000000900460ff1615612069576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005805467ffffffffffffffff1690600061208383615623565b82546101009290920a67ffffffffffffffff8181021990931691831602179091556005541690506000806040519080825280602002602001820160405280156120d6578160200160208202803683370190505b506040805180820182526000808252602080830182815267ffffffffffffffff888116808552600484528685209551865493516bffffffffffffffffffffffff9091167fffffffffffffffffffffffff0000000000000000000000000000000000000000948516176c01000000000000000000000000919093160291909117909455845160608101865233815280830184815281870188815295855260038452959093208351815483166001600160a01b03918216178255955160018201805490931696169590951790559151805194955090936121ba9260028501920190614a3a565b505060405133815267ffffffffffffffff841691507f464722b4166576d3dcbba877b999bc35cf911f4eaf434b7eba68fa113951d0bf9060200160405180910390a250905090565b67ffffffffffffffff8116600090815260036020526040812054819081906060906001600160a01b0316612262576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff80861660009081526004602090815260408083205460038352928190208054600290910180548351818602810186019094528084526bffffffffffffffffffffffff8616966c01000000000000000000000000909604909516946001600160a01b0390921693909291839183018282801561230f57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116122f1575b5050505050905093509350935093509193509193565b600b546601000000000000900460ff161561236c576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146123ce576040517f44b0e3c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208114612408576040517f8129bbcd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000612416828401846150ed565b67ffffffffffffffff81166000908152600360205260409020549091506001600160a01b0316612472576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8116600090815260046020526040812080546bffffffffffffffffffffffff16918691906124a9838561552e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555084600560088282829054906101000a90046bffffffffffffffffffffffff16612500919061552e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508167ffffffffffffffff167fd39ec07f4e209f627a4c427971473820dc129761ba28de8906bd56f57101d4f882878461256791906154ea565b6040805192835260208301919091520161200f565b600b546000906601000000000000900460ff16156125c6576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005a905060008060006125da87876136f7565b9250925092506000866060015163ffffffff1667ffffffffffffffff8111156126055761260561571b565b60405190808252806020026020018201604052801561262e578160200160208202803683370190505b50905060005b876060015163ffffffff168110156126a25760408051602081018590529081018290526060016040516020818303038152906040528051906020012060001c828281518110612685576126856156ec565b60209081029190910101528061269a816155ea565b915050612634565b506000838152600960205260408082208290555181907f1fe543e300000000000000000000000000000000000000000000000000000000906126ea90879086906024016153f1565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090941693909317909252600b80547fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff166601000000000000179055908a015160808b015191925060009161279a9163ffffffff169084613a05565b600b80547fffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffff1690556020808c01805167ffffffffffffffff9081166000908152600490935260408084205492518216845290922080549394506c01000000000000000000000000918290048316936001939192600c9261281e928692900416615502565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060006128758a600b600001600b9054906101000a900463ffffffff1663ffffffff1661286f85612a46565b3a613a53565b6020808e015167ffffffffffffffff166000908152600490915260409020549091506bffffffffffffffffffffffff808316911610156128e1576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020808d015167ffffffffffffffff166000908152600490915260408120805483929061291d9084906bffffffffffffffffffffffff166155bd565b82546101009290920a6bffffffffffffffffffffffff81810219909316918316021790915560008b8152600660209081526040808320546001600160a01b0316835260089091528120805485945090926129799185911661552e565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550877f7dffc5ae5ee4e2e4df1651cf6ad329a73cebdb728f37ea0187b9b17e036756e48883866040516129fc939291909283526bffffffffffffffffffffffff9190911660208301521515604082015260600190565b60405180910390a299505050505050505050505b92915050565b600081604051602001612a29919061523e565b604051602081830303815290604052805190602001209050919050565b6040805161012081018252600c5463ffffffff80821683526401000000008204811660208401526801000000000000000082048116938301939093526c010000000000000000000000008104831660608301527001000000000000000000000000000000008104909216608082015262ffffff740100000000000000000000000000000000000000008304811660a08301819052770100000000000000000000000000000000000000000000008404821660c08401527a0100000000000000000000000000000000000000000000000000008404821660e08401527d0100000000000000000000000000000000000000000000000000000000009093041661010082015260009167ffffffffffffffff841611612b64575192915050565b8267ffffffffffffffff168160a0015162ffffff16108015612b9957508060c0015162ffffff168367ffffffffffffffff1611155b15612ba8576020015192915050565b8267ffffffffffffffff168160c0015162ffffff16108015612bdd57508060e0015162ffffff168367ffffffffffffffff1611155b15612bec576040015192915050565b8267ffffffffffffffff168160e0015162ffffff16108015612c22575080610100015162ffffff168367ffffffffffffffff1611155b15612c31576060015192915050565b6080015192915050565b67ffffffffffffffff821660009081526003602052604090205482906001600160a01b031680612c97576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614612ce4576040517fd8a3fb520000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016108dc565b600b546601000000000000900460ff1615612d2b576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612d3484612fb2565b15612d6b576040517fb42f66e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109e58484613242565b612d7d6131e6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015612df857600080fd5b505afa158015612e0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e309190614e58565b6005549091506801000000000000000090046bffffffffffffffffffffffff1681811115612e94576040517fa99da30200000000000000000000000000000000000000000000000000000000815260048101829052602481018390526044016108dc565b81811015612fad576000612ea882846155a6565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038681166004830152602482018390529192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb90604401602060405180830381600087803b158015612f3057600080fd5b505af1158015612f44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f689190614e36565b50604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a1505b505050565b67ffffffffffffffff81166000908152600360209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561304757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613029575b505050505081525050905060005b8160400151518110156131cb5760005b6007548110156131b857600061318160078381548110613087576130876156ec565b9060005260206000200154856040015185815181106130a8576130a86156ec565b60200260200101518860026000896040015189815181106130cb576130cb6156ec565b6020908102919091018101516001600160a01b03168252818101929092526040908101600090812067ffffffffffffffff808f16835293522054166040805160208082018790526001600160a01b03959095168183015267ffffffffffffffff9384166060820152919092166080808301919091528251808303909101815260a08201835280519084012060c082019490945260e080820185905282518083039091018152610100909101909152805191012091565b50600081815260096020526040902054909150156131a55750600195945050505050565b50806131b0816155ea565b915050613065565b50806131c3816155ea565b915050613055565b5060009392505050565b6131dd6131e6565b61083481613b73565b6000546001600160a01b031633146132405760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016108dc565b565b600b546601000000000000900460ff1615613289576040517fed3ba6a600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff82166000908152600360209081526040808320815160608101835281546001600160a01b0390811682526001830154168185015260028201805484518187028101870186528181529295939486019383018282801561331a57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116132fc575b5050509190925250505067ffffffffffffffff80851660009081526004602090815260408083208151808301909252546bffffffffffffffffffffffff81168083526c01000000000000000000000000909104909416918101919091529293505b8360400151518110156134145760026000856040015183815181106133a2576133a26156ec565b6020908102919091018101516001600160a01b03168252818101929092526040908101600090812067ffffffffffffffff8a168252909252902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690558061340c816155ea565b91505061337b565b5067ffffffffffffffff8516600090815260036020526040812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825560018201805490911690559061346f6002830182614ab7565b505067ffffffffffffffff8516600090815260046020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055600580548291906008906134df9084906801000000000000000090046bffffffffffffffffffffffff166155bd565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb85836bffffffffffffffffffffffff166040518363ffffffff1660e01b815260040161357d9291906001600160a01b03929092168252602082015260400190565b602060405180830381600087803b15801561359757600080fd5b505af11580156135ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135cf9190614e36565b613605576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b03861681526bffffffffffffffffffffffff8316602082015267ffffffffffffffff8716917fe8ed5b475a5b5987aa9165e8731bb78043f39eee32ec5a1169a89e27fcd49815910160405180910390a25050505050565b60004661367381613c35565b156136f05760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136b257600080fd5b505afa1580156136c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136ea9190614e58565b91505090565b4391505090565b60008060006137098560000151612a16565b6000818152600660205260409020549093506001600160a01b03168061375e576040517f77f5b84c000000000000000000000000000000000000000000000000000000008152600481018590526024016108dc565b608086015160405161377d918691602001918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526009909352912054909350806137dc576040517f3688124a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85516020808801516040808a015160608b015160808c01519251613848968b96909594910195865267ffffffffffffffff948516602087015292909316604085015263ffffffff90811660608501529190911660808301526001600160a01b031660a082015260c00190565b604051602081830303815290604052805190602001208114613896576040517fd529142c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006138a58760000151613c58565b9050806139b15786516040517fe9413d3800000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b15801561393157600080fd5b505afa158015613945573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139699190614e58565b9050806139b15786516040517f175dadad00000000000000000000000000000000000000000000000000000000815267ffffffffffffffff90911660048201526024016108dc565b60008860800151826040516020016139d3929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c90506139f88982613d56565b9450505050509250925092565b60005a611388811015613a1757600080fd5b611388810390508460408204820311613a2f57600080fd5b50823b613a3b57600080fd5b60008083516020850160008789f190505b9392505050565b600080613a5e613dc1565b905060008113613a9d576040517f43d4cf66000000000000000000000000000000000000000000000000000000008152600481018290526024016108dc565b6000613aa7613ec8565b9050600082825a613ab88b8b6154ea565b613ac291906155a6565b613acc9088615569565b613ad691906154ea565b613ae890670de0b6b3a7640000615569565b613af29190615555565b90506000613b0b63ffffffff881664e8d4a51000615569565b9050613b23816b033b2e3c9fd0803ce80000006155a6565b821115613b5c576040517fe80fa38100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b613b6681836154ea565b9998505050505050505050565b6001600160a01b038116331415613bcc5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016108dc565b600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061a4b1821480613c49575062066eed82145b80612a1057505062066eee1490565b600046613c6481613c35565b15613d46576101008367ffffffffffffffff16613c7f613667565b613c8991906155a6565b1180613ca65750613c98613667565b8367ffffffffffffffff1610155b15613cb45750600092915050565b6040517f2b407a8200000000000000000000000000000000000000000000000000000000815267ffffffffffffffff84166004820152606490632b407a829060240160206040518083038186803b158015613d0e57600080fd5b505afa158015613d22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a4c9190614e58565b505067ffffffffffffffff164090565b6000613d8a8360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613f1b565b60038360200151604051602001613da29291906153dd565b60408051601f1981840301815291905280516020909101209392505050565b600b54604080517ffeaf968c0000000000000000000000000000000000000000000000000000000081529051600092670100000000000000900463ffffffff169182151591849182917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b158015613e5a57600080fd5b505afa158015613e6e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e929190615132565b509450909250849150508015613eb65750613ead82426155a6565b8463ffffffff16105b15613ec05750600a545b949350505050565b600046613ed481613c35565b15613f1357606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136b257600080fd5b600091505090565b613f2489614156565b613f705760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e20637572766500000000000060448201526064016108dc565b613f7988614156565b613fc55760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e206375727665000000000000000000000060448201526064016108dc565b613fce83614156565b61401a5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e20637572766500000060448201526064016108dc565b61402382614156565b61406f5760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e2063757276650000000060448201526064016108dc565b61407b878a888761422f565b6140c75760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e6573730000000000000060448201526064016108dc565b60006140d38a87614380565b905060006140e6898b878b8689896143e4565b905060006140f7838d8d8a86614510565b9050808a146141485760405162461bcd60e51b815260206004820152600d60248201527f696e76616c69642070726f6f660000000000000000000000000000000000000060448201526064016108dc565b505050505050505050505050565b80516000906401000003d019116141af5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e617465000000000000000000000000000060448201526064016108dc565b60208201516401000003d019116142085760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e617465000000000000000000000000000060448201526064016108dc565b60208201516401000003d0199080096142288360005b6020020151614550565b1492915050565b60006001600160a01b0382166142875760405162461bcd60e51b815260206004820152600b60248201527f626164207769746e65737300000000000000000000000000000000000000000060448201526064016108dc565b60208401516000906001161561429e57601c6142a1565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641418587600060200201510986517ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614358573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614388614ad5565b6143b5600184846040516020016143a19392919061521d565b604051602081830303815290604052614574565b90505b6143c181614156565b612a105780516040805160208101929092526143dd91016143a1565b90506143b8565b6143ec614ad5565b825186516401000003d019908190069106141561444b5760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e6374000060448201526064016108dc565b6144568789886145c3565b6144a25760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c65640000000000000000000060448201526064016108dc565b6144ad8486856145c3565b6144f95760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c656400000000000000000060448201526064016108dc565b61450486848461470b565b98975050505050505050565b60006002868686858760405160200161452e969594939291906151ab565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b61457c614ad5565b614585826147d2565b815261459a61459582600061421e565b61480d565b6020820181905260029006600114156145be576020810180516401000003d0190390525b919050565b6000826146125760405162461bcd60e51b815260206004820152600b60248201527f7a65726f207363616c617200000000000000000000000000000000000000000060448201526064016108dc565b835160208501516000906146289060029061564b565b1561463457601c614637565b601b5b905060007ffffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641418387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa1580156146b7573d6000803e3d6000fd5b5050506020604051035190506000866040516020016146d69190615199565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614713614ad5565b8351602080860151855191860151600093849384936147349390919061482d565b919450925090506401000003d0198582096001146147945760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a0000000000000060448201526064016108dc565b60405180604001604052806401000003d019806147b3576147b361568e565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d01981106145be576040805160208082019390935281518082038401815290820190915280519101206147da565b6000612a108260026148266401000003d01960016154ea565b901c61490d565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a089050600061486d838385856149cd565b909850905061487e88828e886149f1565b909850905061488f88828c876149f1565b909850905060006148a28d878b856149f1565b90985090506148b3888286866149cd565b90985090506148c488828e896149f1565b90985090508181146148f9576401000003d019818a0998506401000003d01982890997506401000003d01981830996506148fd565b8196505b5050505050509450945094915050565b600080614918614af3565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a082015261494a614b11565b60208160c08460057ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9250826149c35760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c75726521000000000000000000000000000060448201526064016108dc565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614aa7579160200282015b82811115614aa757825182547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909116178255602090920191600190910190614a5a565b50614ab3929150614b2f565b5090565b50805460008255906000526020600020908101906108349190614b2f565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614ab35760008155600101614b30565b80356001600160a01b03811681146145be57600080fd5b8060408101831015612a1057600080fd5b600082601f830112614b7d57600080fd5b6040516040810181811067ffffffffffffffff82111715614ba057614ba061571b565b8060405250808385604086011115614bb757600080fd5b60005b6002811015614bd9578135835260209283019290910190600101614bba565b509195945050505050565b600060a08284031215614bf657600080fd5b60405160a0810181811067ffffffffffffffff82111715614c1957614c1961571b565b604052905080614c2883614cae565b8152614c3660208401614cae565b6020820152614c4760408401614c9a565b6040820152614c5860608401614c9a565b6060820152614c6960808401614b44565b60808201525092915050565b803561ffff811681146145be57600080fd5b803562ffffff811681146145be57600080fd5b803563ffffffff811681146145be57600080fd5b803567ffffffffffffffff811681146145be57600080fd5b805169ffffffffffffffffffff811681146145be57600080fd5b600060208284031215614cf257600080fd5b613a4c82614b44565b60008060608385031215614d0e57600080fd5b614d1783614b44565b9150614d268460208501614b5b565b90509250929050565b60008060008060608587031215614d4557600080fd5b614d4e85614b44565b935060208501359250604085013567ffffffffffffffff80821115614d7257600080fd5b818701915087601f830112614d8657600080fd5b813581811115614d9557600080fd5b886020828501011115614da757600080fd5b95989497505060200194505050565b60008060408385031215614dc957600080fd5b614dd283614b44565b915060208301356bffffffffffffffffffffffff81168114614df357600080fd5b809150509250929050565b600060408284031215614e1057600080fd5b613a4c8383614b5b565b600060408284031215614e2c57600080fd5b613a4c8383614b6c565b600060208284031215614e4857600080fd5b81518015158114613a4c57600080fd5b600060208284031215614e6a57600080fd5b5051919050565b600080600080600060a08688031215614e8957600080fd5b85359450614e9960208701614cae565b9350614ea760408701614c75565b9250614eb560608701614c9a565b9150614ec360808701614c9a565b90509295509295909350565b600080828403610240811215614ee457600080fd5b6101a080821215614ef457600080fd5b614efc6154c0565b9150614f088686614b6c565b8252614f178660408701614b6c565b60208301526080850135604083015260a0850135606083015260c08501356080830152614f4660e08601614b44565b60a0830152610100614f5a87828801614b6c565b60c0840152614f6d876101408801614b6c565b60e08401526101808601358184015250819350614f8c86828701614be4565b925050509250929050565b6000806000806000808688036101c0811215614fb257600080fd5b614fbb88614c75565b9650614fc960208901614c9a565b9550614fd760408901614c9a565b9450614fe560608901614c9a565b935060808801359250610120807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff608301121561502057600080fd5b6150286154c0565b915061503660a08a01614c9a565b825261504460c08a01614c9a565b602083015261505560e08a01614c9a565b6040830152610100615068818b01614c9a565b6060840152615078828b01614c9a565b608084015261508a6101408b01614c87565b60a084015261509c6101608b01614c87565b60c08401526150ae6101808b01614c87565b60e08401526150c06101a08b01614c87565b818401525050809150509295509295509295565b6000602082840312156150e657600080fd5b5035919050565b6000602082840312156150ff57600080fd5b613a4c82614cae565b6000806040838503121561511b57600080fd5b61512483614cae565b9150614d2660208401614b44565b600080600080600060a0868803121561514a57600080fd5b61515386614cc6565b9450602086015193506040860151925060608601519150614ec360808701614cc6565b8060005b60028110156109e557815184526020938401939091019060010161517a565b6151a38183615176565b604001919050565b8681526151bb6020820187615176565b6151c86060820186615176565b6151d560a0820185615176565b6151e260e0820184615176565b60609190911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166101208201526101340195945050505050565b83815261522d6020820184615176565b606081019190915260800192915050565b60408101612a108284615176565b600060208083528351808285015260005b818110156152795785810183015185820160400152820161525d565b8181111561528b576000604083870101525b50601f01601f1916929092016040019392505050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b818110156152f2578451835293830193918301916001016152d6565b509098975050505050505050565b60006101c08201905061ffff8816825263ffffffff808816602084015280871660408401528086166060840152846080840152835481811660a085015261535460c08501838360201c1663ffffffff169052565b61536b60e08501838360401c1663ffffffff169052565b6153836101008501838360601c1663ffffffff169052565b61539b6101208501838360801c1663ffffffff169052565b62ffffff60a082901c811661014086015260b882901c811661016086015260d082901c1661018085015260e81c6101a090930192909252979650505050505050565b82815260608101613a4c6020830184615176565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561543257845183529383019391830191600101615416565b5090979650505050505050565b6000608082016bffffffffffffffffffffffff87168352602067ffffffffffffffff8716818501526001600160a01b0380871660408601526080606086015282865180855260a087019150838801945060005b818110156154b0578551841683529484019491840191600101615492565b50909a9950505050505050505050565b604051610120810167ffffffffffffffff811182821017156154e4576154e461571b565b60405290565b600082198211156154fd576154fd61565f565b500190565b600067ffffffffffffffff8083168185168083038211156155255761552561565f565b01949350505050565b60006bffffffffffffffffffffffff8083168185168083038211156155255761552561565f565b6000826155645761556461568e565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156155a1576155a161565f565b500290565b6000828210156155b8576155b861565f565b500390565b60006bffffffffffffffffffffffff838116908316818110156155e2576155e261565f565b039392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561561c5761561c61565f565b5060010190565b600067ffffffffffffffff808316818114156156415761564161565f565b6001019392505050565b60008261565a5761565a61568e565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var VRFCoordinatorV2ABI = VRFCoordinatorV2MetaData.ABI diff --git a/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go b/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go new file mode 100644 index 0000000000..35de7b358a --- /dev/null +++ b/core/gethwrappers/generated/vrf_coordinator_v2_5/vrf_coordinator_v2_5.go @@ -0,0 +1,3950 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrf_coordinator_v2_5 + +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 VRFCoordinatorV25FeeConfig struct { + FulfillmentFlatFeeLinkPPM uint32 + FulfillmentFlatFeeNativePPM uint32 +} + +type VRFCoordinatorV25RequestCommitment struct { + BlockNum uint64 + SubId *big.Int + CallbackGasLimit uint32 + NumWords uint32 + Sender common.Address + ExtraArgs []byte +} + +type VRFProof struct { + Pk [2]*big.Int + Gamma [2]*big.Int + C *big.Int + S *big.Int + Seed *big.Int + UWitness common.Address + CGammaWitness [2]*big.Int + SHashWitness [2]*big.Int + ZInv *big.Int +} + +type VRFV2PlusClientRandomWordsRequest struct { + KeyHash [32]byte + SubId *big.Int + RequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte +} + +var VRFCoordinatorV25MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"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\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"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\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinatorV2_5.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\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":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\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"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\":\"structVRFCoordinatorV2_5.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\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"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\":\"oracleWithdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"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\":\"fulfillmentFlatFeeNativePPM\",\"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_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"}],\"internalType\":\"structVRFCoordinatorV2_5.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200615438038062006154833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615f79620001db600039600081816106150152613a860152615f796000f3fe6080604052600436106102dc5760003560e01c806379ba50971161017f578063b08c8795116100e1578063da2f26101161008a578063e72f6e3011610064578063e72f6e3014610964578063ee9d2d3814610984578063f2fde38b146109b157600080fd5b8063da2f2610146108dd578063dac83d2914610913578063dc311dd31461093357600080fd5b8063caf70c4a116100bb578063caf70c4a1461087d578063cb6317971461089d578063d98e620e146108bd57600080fd5b8063b08c87951461081d578063b2a7cac51461083d578063bec4c08c1461085d57600080fd5b80639b1c385e11610143578063a4c0ed361161011d578063a4c0ed36146107b0578063aa433aff146107d0578063aefb212f146107f057600080fd5b80639b1c385e146107435780639d40a6fd14610763578063a21a23e41461079b57600080fd5b806379ba5097146106bd5780638402595e146106d257806386fe91c7146106f25780638da5cb5b1461071257806395b55cfc1461073057600080fd5b8063330987b31161024357806365982744116101ec5780636b6feccc116101c65780636b6feccc146106375780636f64f03f1461067d57806372e9d5651461069d57600080fd5b806365982744146105c357806366316d8d146105e3578063689c45171461060357600080fd5b806341af6c871161021d57806341af6c871461055e5780635d06b4ab1461058e57806364d51a2a146105ae57600080fd5b8063330987b3146104f3578063405b84fa1461051357806340d6bb821461053357600080fd5b80630ae09540116102a55780631b6b6d231161027f5780631b6b6d231461047f57806329492657146104b7578063294daa49146104d757600080fd5b80630ae09540146103f857806315c48b841461041857806318e3dd271461044057600080fd5b8062012291146102e157806304104edb1461030e578063043bd6ae14610330578063088070f51461035457806308821d58146103d8575b600080fd5b3480156102ed57600080fd5b506102f66109d1565b60405161030593929190615add565b60405180910390f35b34801561031a57600080fd5b5061032e61032936600461542a565b610a4d565b005b34801561033c57600080fd5b5061034660115481565b604051908152602001610305565b34801561036057600080fd5b50600d546103a09061ffff81169063ffffffff62010000820481169160ff600160301b820416916701000000000000008204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a001610305565b3480156103e457600080fd5b5061032e6103f336600461556a565b610c0f565b34801561040457600080fd5b5061032e61041336600461580c565b610da3565b34801561042457600080fd5b5061042d60c881565b60405161ffff9091168152602001610305565b34801561044c57600080fd5b50600a5461046790600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610305565b34801561048b57600080fd5b5060025461049f906001600160a01b031681565b6040516001600160a01b039091168152602001610305565b3480156104c357600080fd5b5061032e6104d2366004615447565b610e71565b3480156104e357600080fd5b5060405160018152602001610305565b3480156104ff57600080fd5b5061046761050e36600461563c565b610fee565b34801561051f57600080fd5b5061032e61052e36600461580c565b6114d8565b34801561053f57600080fd5b506105496101f481565b60405163ffffffff9091168152602001610305565b34801561056a57600080fd5b5061057e6105793660046155bf565b6118ff565b6040519015158152602001610305565b34801561059a57600080fd5b5061032e6105a936600461542a565b611b00565b3480156105ba57600080fd5b5061042d606481565b3480156105cf57600080fd5b5061032e6105de36600461547c565b611bbe565b3480156105ef57600080fd5b5061032e6105fe366004615447565b611c1e565b34801561060f57600080fd5b5061049f7f000000000000000000000000000000000000000000000000000000000000000081565b34801561064357600080fd5b506012546106609063ffffffff8082169164010000000090041682565b6040805163ffffffff938416815292909116602083015201610305565b34801561068957600080fd5b5061032e6106983660046154b5565b611de6565b3480156106a957600080fd5b5060035461049f906001600160a01b031681565b3480156106c957600080fd5b5061032e611ee5565b3480156106de57600080fd5b5061032e6106ed36600461542a565b611f96565b3480156106fe57600080fd5b50600a54610467906001600160601b031681565b34801561071e57600080fd5b506000546001600160a01b031661049f565b61032e61073e3660046155bf565b6120b1565b34801561074f57600080fd5b5061034661075e366004615719565b6121f8565b34801561076f57600080fd5b50600754610783906001600160401b031681565b6040516001600160401b039091168152602001610305565b3480156107a757600080fd5b506103466125ed565b3480156107bc57600080fd5b5061032e6107cb3660046154e2565b61283d565b3480156107dc57600080fd5b5061032e6107eb3660046155bf565b6129dd565b3480156107fc57600080fd5b5061081061080b366004615831565b612a3d565b6040516103059190615a42565b34801561082957600080fd5b5061032e61083836600461576e565b612b3e565b34801561084957600080fd5b5061032e6108583660046155bf565b612cd2565b34801561086957600080fd5b5061032e61087836600461580c565b612e00565b34801561088957600080fd5b50610346610898366004615586565b612f9c565b3480156108a957600080fd5b5061032e6108b836600461580c565b612fcc565b3480156108c957600080fd5b506103466108d83660046155bf565b6132cf565b3480156108e957600080fd5b5061049f6108f83660046155bf565b600e602052600090815260409020546001600160a01b031681565b34801561091f57600080fd5b5061032e61092e36600461580c565b6132f0565b34801561093f57600080fd5b5061095361094e3660046155bf565b61340f565b604051610305959493929190615c45565b34801561097057600080fd5b5061032e61097f36600461542a565b61350a565b34801561099057600080fd5b5061034661099f3660046155bf565b60106020526000908152604090205481565b3480156109bd57600080fd5b5061032e6109cc36600461542a565b6136f2565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff16939192839190830182828015610a3b57602002820191906000526020600020905b815481526020019060010190808311610a27575b50505050509050925092509250909192565b610a55613703565b60135460005b81811015610be257826001600160a01b031660138281548110610a8057610a80615f1d565b6000918252602090912001546001600160a01b03161415610bd0576013610aa8600184615e16565b81548110610ab857610ab8615f1d565b600091825260209091200154601380546001600160a01b039092169183908110610ae457610ae4615f1d565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055826013610b1b600185615e16565b81548110610b2b57610b2b615f1d565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506013805480610b6a57610b6a615f07565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37910160405180910390a1505050565b80610bda81615e85565b915050610a5b565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610c17613703565b604080518082018252600091610c46919084906002908390839080828437600092019190915250612f9c915050565b6000818152600e60205260409020549091506001600160a01b031680610c8257604051631dfd6e1360e21b815260048101839052602401610c03565b6000828152600e6020526040812080546001600160a01b03191690555b600f54811015610d5a5782600f8281548110610cbd57610cbd615f1d565b90600052602060002001541415610d4857600f805460009190610ce290600190615e16565b81548110610cf257610cf2615f1d565b9060005260206000200154905080600f8381548110610d1357610d13615f1d565b600091825260209091200155600f805480610d3057610d30615f07565b60019003818190600052602060002001600090559055505b80610d5281615e85565b915050610c9f565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610d9691815260200190565b60405180910390a2505050565b60008281526005602052604090205482906001600160a01b031680610ddb57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614610e0f57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615610e3a5760405163769dd35360e11b815260040160405180910390fd5b610e43846118ff565b15610e6157604051631685ecdd60e31b815260040160405180910390fd5b610e6b848461375f565b50505050565b600d54600160301b900460ff1615610e9c5760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b0380831691161015610ed857604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c602052604081208054839290610f009084906001600160601b0316615e2d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610f489190615e2d565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610fc2576040519150601f19603f3d011682016040523d82523d6000602084013e610fc7565b606091505b5050905080610fe95760405163950b247960e01b815260040160405180910390fd5b505050565b600d54600090600160301b900460ff161561101c5760405163769dd35360e11b815260040160405180910390fd5b60005a9050600061102d858561391b565b90506000846060015163ffffffff166001600160401b0381111561105357611053615f33565b60405190808252806020026020018201604052801561107c578160200160208202803683370190505b50905060005b856060015163ffffffff168110156110fc578260400151816040516020016110b4929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c8282815181106110df576110df615f1d565b6020908102919091010152806110f481615e85565b915050611082565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b9161113491908690602401615b50565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805466ff0000000000001916600160301b17905590880151608089015191925060009161119c9163ffffffff169084613ba8565b600d805466ff00000000000019169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b03166111df816001615d96565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a0151805161122c90600190615e16565b8151811061123c5761123c615f1d565b602091010151600d5460f89190911c600114915060009061126d908a90600160581b900463ffffffff163a85613bf6565b90508115611376576020808c01516000908152600690915260409020546001600160601b03808316600160601b9092041610156112bd57604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c906112f4908490600160601b90046001600160601b0316615e2d565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c90915281208054859450909261134d91859116615dc1565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550611462565b6020808c01516000908152600690915260409020546001600160601b03808316911610156113b757604051631e9acf1760e31b815260040160405180910390fd5b6020808c0151600090815260069091526040812080548392906113e49084906001600160601b0316615e2d565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b90915281208054859450909261143d91859116615dc1565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a6040015184886040516114bf939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b600d54600160301b900460ff16156115035760405163769dd35360e11b815260040160405180910390fd5b61150c81613c46565b61153457604051635428d44960e01b81526001600160a01b0382166004820152602401610c03565b6000806000806115438661340f565b945094505093509350336001600160a01b0316826001600160a01b0316146115ad5760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610c03565b6115b6866118ff565b156116035760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610c03565b60006040518060c00160405280611618600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b0316815250905060008160405160200161166c9190615a68565b604051602081830303815290604052905061168688613cb0565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b038816906116bf908590600401615a55565b6000604051808303818588803b1580156116d857600080fd5b505af11580156116ec573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150611715905057506001600160601b03861615155b156117f45760025460405163a9059cbb60e01b81526001600160a01b0389811660048301526001600160601b03891660248301529091169063a9059cbb90604401602060405180830381600087803b15801561177057600080fd5b505af1158015611784573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a891906155a2565b6117f45760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c03565b600d805466ff0000000000001916600160301b17905560005b83518110156118a25783818151811061182857611828615f1d565b6020908102919091010151604051638ea9811760e01b81526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b15801561187757600080fd5b505af115801561188b573d6000803e3d6000fd5b50505050808061189a90615e85565b91505061180d565b50600d805466ff00000000000019169055604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561198957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161196b575b505050505081525050905060005b816040015151811015611af65760005b600f54811015611ae3576000611aac600f83815481106119c9576119c9615f1d565b9060005260206000200154856040015185815181106119ea576119ea615f1d565b6020026020010151886004600089604001518981518110611a0d57611a0d615f1d565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081208e82528252829020548251808301889052959093168583015260608501939093526001600160401b039091166080808501919091528151808503909101815260a08401825280519083012060c084019490945260e0808401859052815180850390910181526101009093019052815191012091565b5060008181526010602052604090205490915015611ad05750600195945050505050565b5080611adb81615e85565b9150506119a7565b5080611aee81615e85565b915050611997565b5060009392505050565b611b08613703565b611b1181613c46565b15611b3a5760405163ac8a27ef60e01b81526001600160a01b0382166004820152602401610c03565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b611bc6613703565b6002546001600160a01b031615611bf057604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b600d54600160301b900460ff1615611c495760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b0316611c725760405163c1f0c0a160e01b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b0380831691161015611cae57604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b602052604081208054839290611cd69084906001600160601b0316615e2d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b0316611d1e9190615e2d565b82546101009290920a6001600160601b0381810219909316918316021790915560025460405163a9059cbb60e01b81526001600160a01b03868116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b158015611d8d57600080fd5b505af1158015611da1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc591906155a2565b611de257604051631e9acf1760e31b815260040160405180910390fd5b5050565b611dee613703565b604080518082018252600091611e1d919084906002908390839080828437600092019190915250612f9c915050565b6000818152600e60205260409020549091506001600160a01b031615611e5957604051634a0b8fa760e01b815260048101829052602401610c03565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610d96565b6001546001600160a01b03163314611f3f5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c03565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611f9e613703565b600a544790600160601b90046001600160601b031681811115611fde576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015610fe9576000611ff28284615e16565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114612041576040519150601f19603f3d011682016040523d82523d6000602084013e612046565b606091505b50509050806120685760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c910160405180910390a15050505050565b600d54600160301b900460ff16156120dc5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b031661211157604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c6121408385615dc1565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b03166121889190615dc1565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e9028234846121db9190615d7e565b604080519283526020830191909152015b60405180910390a25050565b600d54600090600160301b900460ff16156122265760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b031661226157604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b0316806122b2576040516379bfd40160e01b815260208401356004820152336024820152604401610c03565b600d5461ffff166122c96060850160408601615753565b61ffff1610806122ec575060c86122e66060850160408601615753565b61ffff16115b15612332576123016060840160408501615753565b600d5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610c03565b600d5462010000900463ffffffff166123516080850160608601615853565b63ffffffff1611156123a15761236d6080840160608501615853565b600d54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610c03565b6101f46123b460a0850160808601615853565b63ffffffff1611156123fa576123d060a0840160808501615853565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610c03565b6000612407826001615d96565b604080518635602080830182905233838501528089013560608401526001600160401b0385166080808501919091528451808503909101815260a0808501865281519183019190912060c085019390935260e0808501849052855180860390910181526101009094019094528251920191909120929350906000906124979061249290890189615c9a565b613eff565b905060006124a482613f7c565b9050836124af613fed565b60208a01356124c460808c0160608d01615853565b6124d460a08d0160808e01615853565b33866040516020016124ec9796959493929190615ba8565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d60400160208101906125639190615753565b8e60600160208101906125769190615853565b8f60800160208101906125899190615853565b8960405161259c96959493929190615b69565b60405180910390a450503360009081526004602090815260408083208983013584529091529020805467ffffffffffffffff19166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff161561261b5760405163769dd35360e11b815260040160405180910390fd5b600033612629600143615e16565b600754604051606093841b6bffffffffffffffffffffffff199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b039091169060006126a883615ea0565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b038111156126e7576126e7615f33565b604051908082528060200260200182016040528015612710578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b0392831617835592516001830180549094169116179091559251805194955090936127f19260028501920190615140565b506128019150600890508361407d565b5060405133815282907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a250905090565b600d54600160301b900460ff16156128685760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b03163314612893576040516344b0e3c360e01b815260040160405180910390fd5b602081146128b457604051638129bbcd60e01b815260040160405180910390fd5b60006128c2828401846155bf565b6000818152600560205260409020549091506001600160a01b03166128fa57604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b0316918691906129218385615dc1565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166129699190615dc1565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846129bc9190615d7e565b604080519283526020830191909152015b60405180910390a2505050505050565b6129e5613703565b6000818152600560205260409020546001600160a01b0316612a1a57604051630fb532db60e11b815260040160405180910390fd5b600081815260056020526040902054610c0c9082906001600160a01b031661375f565b60606000612a4b6008614089565b9050808410612a6d57604051631390f2a160e01b815260040160405180910390fd5b6000612a798486615d7e565b905081811180612a87575083155b612a915780612a93565b815b90506000612aa18683615e16565b6001600160401b03811115612ab857612ab8615f33565b604051908082528060200260200182016040528015612ae1578160200160208202803683370190505b50905060005b8151811015612b3457612b05612afd8883615d7e565b600890614093565b828281518110612b1757612b17615f1d565b602090810291909101015280612b2c81615e85565b915050612ae7565b5095945050505050565b612b46613703565b60c861ffff87161115612b805760405163539c34bb60e11b815261ffff871660048201819052602482015260c86044820152606401610c03565b60008213612ba4576040516321ea67b360e11b815260048101839052602401610c03565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff19168817620100008702176effffffffffffffffff000000000000191667010000000000000085026effffffff0000000000000000000000191617600160581b83021790558a51601280548d87015192891667ffffffffffffffff199091161764010000000092891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff1615612cfd5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b0316612d3257604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612d8b576000818152600560205260409081902060010154905163d084e97560e01b81526001600160a01b039091166004820152602401610c03565b6000818152600560209081526040918290208054336001600160a01b0319808316821784556001909301805490931690925583516001600160a01b0390911680825292810191909152909183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691016121ec565b60008281526005602052604090205482906001600160a01b031680612e3857604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612e6c57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612e975760405163769dd35360e11b815260040160405180910390fd5b60008481526005602052604090206002015460641415612eca576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b031615612f0157610e6b565b6001600160a01b03831660008181526004602090815260408083208884528252808320805467ffffffffffffffff19166001908117909155600583528184206002018054918201815584529282902090920180546001600160a01b03191684179055905191825285917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a250505050565b600081604051602001612faf9190615a34565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b03168061300457604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461303857604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff16156130635760405163769dd35360e11b815260040160405180910390fd5b61306c846118ff565b1561308a57604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b03166130e6576040516379bfd40160e01b8152600481018590526001600160a01b0384166024820152604401610c03565b60008481526005602090815260408083206002018054825181850281018501909352808352919290919083018282801561314957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161312b575b505050505090506000600182516131609190615e16565b905060005b825181101561326c57856001600160a01b031683828151811061318a5761318a615f1d565b60200260200101516001600160a01b0316141561325a5760008383815181106131b5576131b5615f1d565b6020026020010151905080600560008a815260200190815260200160002060020183815481106131e7576131e7615f1d565b600091825260208083209190910180546001600160a01b0319166001600160a01b03949094169390931790925589815260059091526040902060020180548061323257613232615f07565b600082815260209020810160001990810180546001600160a01b03191690550190555061326c565b8061326481615e85565b915050613165565b506001600160a01b03851660008181526004602090815260408083208a8452825291829020805467ffffffffffffffff19169055905191825287917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a791016129cd565b600f81815481106132df57600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b03168061332857604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461335c57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff16156133875760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b03848116911614610e6b5760008481526005602090815260409182902060010180546001600160a01b0319166001600160a01b03871690811790915582513381529182015285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19101612f8e565b6000818152600560205260408120548190819081906060906001600160a01b031661344d57604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b03909416939183918301828280156134f057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116134d2575b505050505090509450945094509450945091939590929450565b613512613703565b6002546001600160a01b031661353b5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561357f57600080fd5b505afa158015613593573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135b791906155d8565b600a549091506001600160601b0316818111156135f1576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015610fe95760006136058284615e16565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b15801561365557600080fd5b505af1158015613669573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061368d91906155a2565b6136aa57604051631f01ff1360e21b815260040160405180910390fd5b604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b6136fa613703565b610c0c8161409f565b6000546001600160a01b0316331461375d5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c03565b565b60008061376b84613cb0565b60025491935091506001600160a01b03161580159061379257506001600160601b03821615155b156138425760025460405163a9059cbb60e01b81526001600160a01b0385811660048301526001600160601b03851660248301529091169063a9059cbb90604401602060405180830381600087803b1580156137ed57600080fd5b505af1158015613801573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382591906155a2565b61384257604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613898576040519150601f19603f3d011682016040523d82523d6000602084013e61389d565b606091505b50509050806138bf5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b604080516060810182526000808252602082018190529181019190915260006139478460000151612f9c565b6000818152600e60205260409020549091506001600160a01b03168061398357604051631dfd6e1360e21b815260048101839052602401610c03565b60008286608001516040516020016139a5929190918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526010909352912054909150806139eb57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d01519351613a1a978a979096959101615bf2565b604051602081830303815290604052805190602001208114613a4f5760405163354a450b60e21b815260040160405180910390fd5b6000613a5e8760000151614149565b905080613b36578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b158015613ad057600080fd5b505afa158015613ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0891906155d8565b905080613b3657865160405163175dadad60e01b81526001600160401b039091166004820152602401610c03565b6000886080015182604051602001613b58929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c90506000613b7f8a8361422a565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a611388811015613bba57600080fd5b611388810390508460408204820311613bd257600080fd5b50823b613bde57600080fd5b60008083516020850160008789f190505b9392505050565b60008115613c2457601254613c1d9086908690640100000000900463ffffffff1686614295565b9050613c3e565b601254613c3b908690869063ffffffff16866142ff565b90505b949350505050565b6000805b601354811015613ca757826001600160a01b031660138281548110613c7157613c71615f1d565b6000918252602090912001546001600160a01b03161415613c955750600192915050565b80613c9f81615e85565b915050613c4a565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287968796949594860193919290830182828015613d3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613d1e575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613e19576004600084604001518381518110613dc857613dc8615f1d565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208982529092529020805467ffffffffffffffff1916905580613e1181615e85565b915050613da1565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613e5160028301826151a5565b5050600085815260066020526040812055613e6d6008866143ed565b50600a8054859190600090613e8c9084906001600160601b0316615e2d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613ed49190615e2d565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081019091526000815281613f2857506040805160208101909152600081526114d2565b63125fa26760e31b613f3a8385615e55565b6001600160e01b03191614613f6257604051632923fee760e11b815260040160405180910390fd5b613f6f8260048186615d54565b810190613bef91906155f1565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613fb591511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b600046613ff9816143f9565b156140765760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561403857600080fd5b505afa15801561404c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061407091906155d8565b91505090565b4391505090565b6000613bef838361441c565b60006114d2825490565b6000613bef838361446b565b6001600160a01b0381163314156140f85760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c03565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046614155816143f9565b1561421b57610100836001600160401b031661416f613fed565b6141799190615e16565b11806141955750614188613fed565b836001600160401b031610155b156141a35750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a829060240160206040518083038186803b1580156141e357600080fd5b505afa1580156141f7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bef91906155d8565b50506001600160401b03164090565b600061425e8360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151614495565b60038360200151604051602001614276929190615b3c565b60408051601f1981840301815291905280516020909101209392505050565b6000806142a06146c0565b905060005a6142af8888615d7e565b6142b99190615e16565b6142c39085615df7565b905060006142dc63ffffffff871664e8d4a51000615df7565b9050826142e98284615d7e565b6142f39190615d7e565b98975050505050505050565b60008061430a614713565b905060008113614330576040516321ea67b360e11b815260048101829052602401610c03565b600061433a6146c0565b9050600082825a61434b8b8b615d7e565b6143559190615e16565b61435f9088615df7565b6143699190615d7e565b61437b90670de0b6b3a7640000615df7565b6143859190615de3565b9050600061439e63ffffffff881664e8d4a51000615df7565b90506143b6816b033b2e3c9fd0803ce8000000615e16565b8211156143d65760405163e80fa38160e01b815260040160405180910390fd5b6143e08183615d7e565b9998505050505050505050565b6000613bef83836147e2565b600061a4b182148061440d575062066eed82145b806114d257505062066eee1490565b6000818152600183016020526040812054614463575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556114d2565b5060006114d2565b600082600001828154811061448257614482615f1d565b9060005260206000200154905092915050565b61449e896148d5565b6144ea5760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610c03565b6144f3886148d5565b61453f5760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610c03565b614548836148d5565b6145945760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610c03565b61459d826148d5565b6145e95760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610c03565b6145f5878a88876149ae565b6146415760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610c03565b600061464d8a87614ad1565b90506000614660898b878b868989614b35565b90506000614671838d8d8a86614c55565b9050808a146146b25760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610c03565b505050505050505050505050565b6000466146cc816143f9565b1561470b57606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561403857600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093670100000000000000900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561477557600080fd5b505afa158015614789573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147ad919061586e565b5094509092508491505080156147d157506147c88242615e16565b8463ffffffff16105b15613c3e5750601154949350505050565b600081815260018301602052604081205480156148cb576000614806600183615e16565b855490915060009061481a90600190615e16565b905081811461487f57600086600001828154811061483a5761483a615f1d565b906000526020600020015490508087600001848154811061485d5761485d615f1d565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061489057614890615f07565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506114d2565b60009150506114d2565b80516000906401000003d0191161492e5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d019116149875760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d0199080096149a78360005b6020020151614c95565b1492915050565b60006001600160a01b0382166149f45760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610c03565b602084015160009060011615614a0b57601c614a0e565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614aa9573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614ad96151c3565b614b0660018484604051602001614af293929190615a13565b604051602081830303815290604052614cb9565b90505b614b12816148d5565b6114d2578051604080516020810192909252614b2e9101614af2565b9050614b09565b614b3d6151c3565b825186516401000003d0199081900691061415614b9c5760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610c03565b614ba7878988614d07565b614bf35760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610c03565b614bfe848685614d07565b614c4a5760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610c03565b6142f3868484614e2f565b600060028686868587604051602001614c73969594939291906159b4565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614cc16151c3565b614cca82614ef6565b8152614cdf614cda82600061499d565b614f31565b6020820181905260029006600114156125e8576020810180516401000003d019039052919050565b600082614d445760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610c03565b83516020850151600090614d5a90600290615ec7565b15614d6657601c614d69565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614ddb573d6000803e3d6000fd5b505050602060405103519050600086604051602001614dfa91906159a2565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614e376151c3565b835160208086015185519186015160009384938493614e5893909190614f51565b919450925090506401000003d019858209600114614eb85760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610c03565b60405180604001604052806401000003d01980614ed757614ed7615ef1565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d01981106125e857604080516020808201939093528151808203840181529082019091528051910120614efe565b60006114d2826002614f4a6401000003d0196001615d7e565b901c615031565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614f91838385856150d3565b9098509050614fa288828e886150f7565b9098509050614fb388828c876150f7565b90985090506000614fc68d878b856150f7565b9098509050614fd7888286866150d3565b9098509050614fe888828e896150f7565b909850905081811461501d576401000003d019818a0998506401000003d01982890997506401000003d0198183099650615021565b8196505b5050505050509450945094915050565b60008061503c6151e1565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a082015261506e6151ff565b60208160c0846005600019fa9250826150c95760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610c03565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215615195579160200282015b8281111561519557825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615160565b506151a192915061521d565b5090565b5080546000825590600052602060002090810190610c0c919061521d565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b808211156151a1576000815560010161521e565b80356125e881615f49565b80604081018310156114d257600080fd5b600082601f83011261525f57600080fd5b615267615ce7565b80838560408601111561527957600080fd5b60005b600281101561529b57813584526020938401939091019060010161527c565b509095945050505050565b600082601f8301126152b757600080fd5b81356001600160401b03808211156152d1576152d1615f33565b604051601f8301601f19908116603f011681019082821181831017156152f9576152f9615f33565b8160405283815286602085880101111561531257600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060c0828403121561534457600080fd5b61534c615d0f565b905081356001600160401b03808216821461536657600080fd5b8183526020840135602084015261537f604085016153e5565b6040840152615390606085016153e5565b60608401526153a160808501615232565b608084015260a08401359150808211156153ba57600080fd5b506153c7848285016152a6565b60a08301525092915050565b803561ffff811681146125e857600080fd5b803563ffffffff811681146125e857600080fd5b805169ffffffffffffffffffff811681146125e857600080fd5b80356001600160601b03811681146125e857600080fd5b60006020828403121561543c57600080fd5b8135613bef81615f49565b6000806040838503121561545a57600080fd5b823561546581615f49565b915061547360208401615413565b90509250929050565b6000806040838503121561548f57600080fd5b823561549a81615f49565b915060208301356154aa81615f49565b809150509250929050565b600080606083850312156154c857600080fd5b82356154d381615f49565b9150615473846020850161523d565b600080600080606085870312156154f857600080fd5b843561550381615f49565b93506020850135925060408501356001600160401b038082111561552657600080fd5b818701915087601f83011261553a57600080fd5b81358181111561554957600080fd5b88602082850101111561555b57600080fd5b95989497505060200194505050565b60006040828403121561557c57600080fd5b613bef838361523d565b60006040828403121561559857600080fd5b613bef838361524e565b6000602082840312156155b457600080fd5b8151613bef81615f5e565b6000602082840312156155d157600080fd5b5035919050565b6000602082840312156155ea57600080fd5b5051919050565b60006020828403121561560357600080fd5b604051602081018181106001600160401b038211171561562557615625615f33565b604052823561563381615f5e565b81529392505050565b6000808284036101c081121561565157600080fd5b6101a08082121561566157600080fd5b615669615d31565b9150615675868661524e565b8252615684866040870161524e565b60208301526080850135604083015260a0850135606083015260c085013560808301526156b360e08601615232565b60a08301526101006156c78782880161524e565b60c08401526156da87610140880161524e565b60e0840152610180860135908301529092508301356001600160401b0381111561570357600080fd5b61570f85828601615332565b9150509250929050565b60006020828403121561572b57600080fd5b81356001600160401b0381111561574157600080fd5b820160c08185031215613bef57600080fd5b60006020828403121561576557600080fd5b613bef826153d3565b60008060008060008086880360e081121561578857600080fd5b615791886153d3565b965061579f602089016153e5565b95506157ad604089016153e5565b94506157bb606089016153e5565b9350608088013592506040609f19820112156157d657600080fd5b506157df615ce7565b6157eb60a089016153e5565b81526157f960c089016153e5565b6020820152809150509295509295509295565b6000806040838503121561581f57600080fd5b8235915060208301356154aa81615f49565b6000806040838503121561584457600080fd5b50508035926020909101359150565b60006020828403121561586557600080fd5b613bef826153e5565b600080600080600060a0868803121561588657600080fd5b61588f866153f9565b94506020860151935060408601519250606086015191506158b2608087016153f9565b90509295509295909350565b600081518084526020808501945080840160005b838110156158f75781516001600160a01b0316875295820195908201906001016158d2565b509495945050505050565b8060005b6002811015610e6b578151845260209384019390910190600101615906565b600081518084526020808501945080840160005b838110156158f757815187529582019590820190600101615939565b6000815180845260005b8181101561597b5760208185018101518683018201520161595f565b8181111561598d576000602083870101525b50601f01601f19169290920160200192915050565b6159ac8183615902565b604001919050565b8681526159c46020820187615902565b6159d16060820186615902565b6159de60a0820185615902565b6159eb60e0820184615902565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b838152615a236020820184615902565b606081019190915260800192915050565b604081016114d28284615902565b602081526000613bef6020830184615925565b602081526000613bef6020830184615955565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c06080840152615aae60e08401826158be565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615b2e57845183529383019391830191600101615b12565b509098975050505050505050565b82815260608101613bef6020830184615902565b828152604060208201526000613c3e6040830184615925565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a08301526142f360c0830184615955565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143e060e0830184615955565b8781526001600160401b0387166020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143e060e0830184615955565b60006001600160601b0380881683528087166020840152506001600160401b03851660408301526001600160a01b038416606083015260a06080830152615c8f60a08301846158be565b979650505050505050565b6000808335601e19843603018112615cb157600080fd5b8301803591506001600160401b03821115615ccb57600080fd5b602001915036819003821315615ce057600080fd5b9250929050565b604080519081016001600160401b0381118282101715615d0957615d09615f33565b60405290565b60405160c081016001600160401b0381118282101715615d0957615d09615f33565b60405161012081016001600160401b0381118282101715615d0957615d09615f33565b60008085851115615d6457600080fd5b83861115615d7157600080fd5b5050820193919092039150565b60008219821115615d9157615d91615edb565b500190565b60006001600160401b03808316818516808303821115615db857615db8615edb565b01949350505050565b60006001600160601b03808316818516808303821115615db857615db8615edb565b600082615df257615df2615ef1565b500490565b6000816000190483118215151615615e1157615e11615edb565b500290565b600082821015615e2857615e28615edb565b500390565b60006001600160601b0383811690831681811015615e4d57615e4d615edb565b039392505050565b6001600160e01b03198135818116916004851015615e7d5780818660040360031b1b83161692505b505092915050565b6000600019821415615e9957615e99615edb565b5060010190565b60006001600160401b0380831681811415615ebd57615ebd615edb565b6001019392505050565b600082615ed657615ed6615ef1565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c0c57600080fd5b8015158114610c0c57600080fdfea164736f6c6343000806000a", +} + +var VRFCoordinatorV25ABI = VRFCoordinatorV25MetaData.ABI + +var VRFCoordinatorV25Bin = VRFCoordinatorV25MetaData.Bin + +func DeployVRFCoordinatorV25(auth *bind.TransactOpts, backend bind.ContractBackend, blockhashStore common.Address) (common.Address, *types.Transaction, *VRFCoordinatorV25, error) { + parsed, err := VRFCoordinatorV25MetaData.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(VRFCoordinatorV25Bin), backend, blockhashStore) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VRFCoordinatorV25{VRFCoordinatorV25Caller: VRFCoordinatorV25Caller{contract: contract}, VRFCoordinatorV25Transactor: VRFCoordinatorV25Transactor{contract: contract}, VRFCoordinatorV25Filterer: VRFCoordinatorV25Filterer{contract: contract}}, nil +} + +type VRFCoordinatorV25 struct { + address common.Address + abi abi.ABI + VRFCoordinatorV25Caller + VRFCoordinatorV25Transactor + VRFCoordinatorV25Filterer +} + +type VRFCoordinatorV25Caller struct { + contract *bind.BoundContract +} + +type VRFCoordinatorV25Transactor struct { + contract *bind.BoundContract +} + +type VRFCoordinatorV25Filterer struct { + contract *bind.BoundContract +} + +type VRFCoordinatorV25Session struct { + Contract *VRFCoordinatorV25 + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorV25CallerSession struct { + Contract *VRFCoordinatorV25Caller + CallOpts bind.CallOpts +} + +type VRFCoordinatorV25TransactorSession struct { + Contract *VRFCoordinatorV25Transactor + TransactOpts bind.TransactOpts +} + +type VRFCoordinatorV25Raw struct { + Contract *VRFCoordinatorV25 +} + +type VRFCoordinatorV25CallerRaw struct { + Contract *VRFCoordinatorV25Caller +} + +type VRFCoordinatorV25TransactorRaw struct { + Contract *VRFCoordinatorV25Transactor +} + +func NewVRFCoordinatorV25(address common.Address, backend bind.ContractBackend) (*VRFCoordinatorV25, error) { + abi, err := abi.JSON(strings.NewReader(VRFCoordinatorV25ABI)) + if err != nil { + return nil, err + } + contract, err := bindVRFCoordinatorV25(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25{address: address, abi: abi, VRFCoordinatorV25Caller: VRFCoordinatorV25Caller{contract: contract}, VRFCoordinatorV25Transactor: VRFCoordinatorV25Transactor{contract: contract}, VRFCoordinatorV25Filterer: VRFCoordinatorV25Filterer{contract: contract}}, nil +} + +func NewVRFCoordinatorV25Caller(address common.Address, caller bind.ContractCaller) (*VRFCoordinatorV25Caller, error) { + contract, err := bindVRFCoordinatorV25(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25Caller{contract: contract}, nil +} + +func NewVRFCoordinatorV25Transactor(address common.Address, transactor bind.ContractTransactor) (*VRFCoordinatorV25Transactor, error) { + contract, err := bindVRFCoordinatorV25(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25Transactor{contract: contract}, nil +} + +func NewVRFCoordinatorV25Filterer(address common.Address, filterer bind.ContractFilterer) (*VRFCoordinatorV25Filterer, error) { + contract, err := bindVRFCoordinatorV25(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25Filterer{contract: contract}, nil +} + +func bindVRFCoordinatorV25(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VRFCoordinatorV25MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinatorV25.Contract.VRFCoordinatorV25Caller.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.VRFCoordinatorV25Transactor.contract.Transfer(opts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.VRFCoordinatorV25Transactor.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFCoordinatorV25.Contract.contract.Call(opts, result, method, params...) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.contract.Transfer(opts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.contract.Transact(opts, method, params...) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) BLOCKHASHSTORE(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "BLOCKHASH_STORE") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) BLOCKHASHSTORE() (common.Address, error) { + return _VRFCoordinatorV25.Contract.BLOCKHASHSTORE(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) BLOCKHASHSTORE() (common.Address, error) { + return _VRFCoordinatorV25.Contract.BLOCKHASHSTORE(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) LINK(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Session) LINK() (common.Address, error) { + return _VRFCoordinatorV25.Contract.LINK(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) LINK() (common.Address, error) { + return _VRFCoordinatorV25.Contract.LINK(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "LINK_NATIVE_FEED") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) LINKNATIVEFEED() (common.Address, error) { + return _VRFCoordinatorV25.Contract.LINKNATIVEFEED(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) LINKNATIVEFEED() (common.Address, error) { + return _VRFCoordinatorV25.Contract.LINKNATIVEFEED(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Session) MAXCONSUMERS() (uint16, error) { + return _VRFCoordinatorV25.Contract.MAXCONSUMERS(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) MAXCONSUMERS() (uint16, error) { + return _VRFCoordinatorV25.Contract.MAXCONSUMERS(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) MAXNUMWORDS(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "MAX_NUM_WORDS") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) MAXNUMWORDS() (uint32, error) { + return _VRFCoordinatorV25.Contract.MAXNUMWORDS(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) MAXNUMWORDS() (uint32, error) { + return _VRFCoordinatorV25.Contract.MAXNUMWORDS(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) MAXREQUESTCONFIRMATIONS(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "MAX_REQUEST_CONFIRMATIONS") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) MAXREQUESTCONFIRMATIONS() (uint16, error) { + return _VRFCoordinatorV25.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) MAXREQUESTCONFIRMATIONS() (uint16, error) { + return _VRFCoordinatorV25.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Session) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorV25.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorV25.CallOpts, startIndex, maxCount) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _VRFCoordinatorV25.Contract.GetActiveSubscriptionIds(&_VRFCoordinatorV25.CallOpts, startIndex, maxCount) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) GetRequestConfig(opts *bind.CallOpts) (uint16, uint32, [][32]byte, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "getRequestConfig") + + if err != nil { + return *new(uint16), *new(uint32), *new([][32]byte), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + out1 := *abi.ConvertType(out[1], new(uint32)).(*uint32) + out2 := *abi.ConvertType(out[2], new([][32]byte)).(*[][32]byte) + + return out0, out1, out2, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) GetRequestConfig() (uint16, uint32, [][32]byte, error) { + return _VRFCoordinatorV25.Contract.GetRequestConfig(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) GetRequestConfig() (uint16, uint32, [][32]byte, error) { + return _VRFCoordinatorV25.Contract.GetRequestConfig(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "getSubscription", subId) + + outstruct := new(GetSubscription) + if err != nil { + return *outstruct, err + } + + outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.NativeBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + 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 + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinatorV25.Contract.GetSubscription(&_VRFCoordinatorV25.CallOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _VRFCoordinatorV25.Contract.GetSubscription(&_VRFCoordinatorV25.CallOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) HashOfKey(opts *bind.CallOpts, publicKey [2]*big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "hashOfKey", publicKey) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) { + return _VRFCoordinatorV25.Contract.HashOfKey(&_VRFCoordinatorV25.CallOpts, publicKey) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) { + return _VRFCoordinatorV25.Contract.HashOfKey(&_VRFCoordinatorV25.CallOpts, publicKey) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) MigrationVersion(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "migrationVersion") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) MigrationVersion() (uint8, error) { + return _VRFCoordinatorV25.Contract.MigrationVersion(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) MigrationVersion() (uint8, error) { + return _VRFCoordinatorV25.Contract.MigrationVersion(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Session) Owner() (common.Address, error) { + return _VRFCoordinatorV25.Contract.Owner(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) Owner() (common.Address, error) { + return _VRFCoordinatorV25.Contract.Owner(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "pendingRequestExists", subId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) PendingRequestExists(subId *big.Int) (bool, error) { + return _VRFCoordinatorV25.Contract.PendingRequestExists(&_VRFCoordinatorV25.CallOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) PendingRequestExists(subId *big.Int) (bool, error) { + return _VRFCoordinatorV25.Contract.PendingRequestExists(&_VRFCoordinatorV25.CallOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) SConfig(opts *bind.CallOpts) (SConfig, + + error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "s_config") + + outstruct := new(SConfig) + if err != nil { + return *outstruct, err + } + + outstruct.MinimumRequestConfirmations = *abi.ConvertType(out[0], new(uint16)).(*uint16) + outstruct.MaxGasLimit = *abi.ConvertType(out[1], 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 + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) SConfig() (SConfig, + + error) { + return _VRFCoordinatorV25.Contract.SConfig(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) SConfig() (SConfig, + + error) { + return _VRFCoordinatorV25.Contract.SConfig(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "s_currentSubNonce") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) SCurrentSubNonce() (uint64, error) { + return _VRFCoordinatorV25.Contract.SCurrentSubNonce(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) SCurrentSubNonce() (uint64, error) { + return _VRFCoordinatorV25.Contract.SCurrentSubNonce(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "s_fallbackWeiPerUnitLink") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) SFallbackWeiPerUnitLink() (*big.Int, error) { + return _VRFCoordinatorV25.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) SFallbackWeiPerUnitLink() (*big.Int, error) { + return _VRFCoordinatorV25.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) SFeeConfig(opts *bind.CallOpts) (SFeeConfig, + + error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "s_feeConfig") + + outstruct := new(SFeeConfig) + if err != nil { + return *outstruct, err + } + + outstruct.FulfillmentFlatFeeLinkPPM = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.FulfillmentFlatFeeNativePPM = *abi.ConvertType(out[1], new(uint32)).(*uint32) + + return *outstruct, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) SFeeConfig() (SFeeConfig, + + error) { + return _VRFCoordinatorV25.Contract.SFeeConfig(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) SFeeConfig() (SFeeConfig, + + error) { + return _VRFCoordinatorV25.Contract.SFeeConfig(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "s_provingKeyHashes", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorV25.Contract.SProvingKeyHashes(&_VRFCoordinatorV25.CallOpts, arg0) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorV25.Contract.SProvingKeyHashes(&_VRFCoordinatorV25.CallOpts, arg0) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (common.Address, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "s_provingKeys", arg0) + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) SProvingKeys(arg0 [32]byte) (common.Address, error) { + return _VRFCoordinatorV25.Contract.SProvingKeys(&_VRFCoordinatorV25.CallOpts, arg0) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) SProvingKeys(arg0 [32]byte) (common.Address, error) { + return _VRFCoordinatorV25.Contract.SProvingKeys(&_VRFCoordinatorV25.CallOpts, arg0) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "s_requestCommitments", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) SRequestCommitments(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorV25.Contract.SRequestCommitments(&_VRFCoordinatorV25.CallOpts, arg0) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) SRequestCommitments(arg0 *big.Int) ([32]byte, error) { + return _VRFCoordinatorV25.Contract.SRequestCommitments(&_VRFCoordinatorV25.CallOpts, arg0) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) STotalBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV25.contract.Call(opts, &out, "s_totalBalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) STotalBalance() (*big.Int, error) { + return _VRFCoordinatorV25.Contract.STotalBalance(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) STotalBalance() (*big.Int, error) { + return _VRFCoordinatorV25.Contract.STotalBalance(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Caller) STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Session) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorV25.Contract.STotalNativeBalance(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25CallerSession) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorV25.Contract.STotalNativeBalance(&_VRFCoordinatorV25.CallOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "acceptOwnership") +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) AcceptOwnership() (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.AcceptOwnership(&_VRFCoordinatorV25.TransactOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.AcceptOwnership(&_VRFCoordinatorV25.TransactOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorV25.TransactOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorV25.TransactOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "addConsumer", subId, consumer) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.AddConsumer(&_VRFCoordinatorV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.AddConsumer(&_VRFCoordinatorV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "cancelSubscription", subId, to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.CancelSubscription(&_VRFCoordinatorV25.TransactOpts, subId, to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.CancelSubscription(&_VRFCoordinatorV25.TransactOpts, subId, to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "createSubscription") +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) CreateSubscription() (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.CreateSubscription(&_VRFCoordinatorV25.TransactOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) CreateSubscription() (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.CreateSubscription(&_VRFCoordinatorV25.TransactOpts) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "deregisterMigratableCoordinator", target) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.DeregisterMigratableCoordinator(&_VRFCoordinatorV25.TransactOpts, target) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.DeregisterMigratableCoordinator(&_VRFCoordinatorV25.TransactOpts, target) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) DeregisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "deregisterProvingKey", publicProvingKey) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) DeregisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.DeregisterProvingKey(&_VRFCoordinatorV25.TransactOpts, publicProvingKey) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) DeregisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.DeregisterProvingKey(&_VRFCoordinatorV25.TransactOpts, publicProvingKey) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV25RequestCommitment) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "fulfillRandomWords", proof, rc) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV25RequestCommitment) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.FulfillRandomWords(&_VRFCoordinatorV25.TransactOpts, proof, rc) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV25RequestCommitment) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.FulfillRandomWords(&_VRFCoordinatorV25.TransactOpts, proof, rc) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "fundSubscriptionWithNative", subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.FundSubscriptionWithNative(&_VRFCoordinatorV25.TransactOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.FundSubscriptionWithNative(&_VRFCoordinatorV25.TransactOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "migrate", subId, newCoordinator) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.Migrate(&_VRFCoordinatorV25.TransactOpts, subId, newCoordinator) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.Migrate(&_VRFCoordinatorV25.TransactOpts, subId, newCoordinator) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "onTokenTransfer", arg0, amount, data) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.OnTokenTransfer(&_VRFCoordinatorV25.TransactOpts, arg0, amount, data) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.OnTokenTransfer(&_VRFCoordinatorV25.TransactOpts, arg0, amount, data) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "oracleWithdraw", recipient, amount) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.OracleWithdraw(&_VRFCoordinatorV25.TransactOpts, recipient, amount) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.OracleWithdraw(&_VRFCoordinatorV25.TransactOpts, recipient, amount) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) OracleWithdrawNative(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "oracleWithdrawNative", recipient, amount) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) OracleWithdrawNative(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.OracleWithdrawNative(&_VRFCoordinatorV25.TransactOpts, recipient, amount) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) OracleWithdrawNative(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.OracleWithdrawNative(&_VRFCoordinatorV25.TransactOpts, recipient, amount) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "ownerCancelSubscription", subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.OwnerCancelSubscription(&_VRFCoordinatorV25.TransactOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.OwnerCancelSubscription(&_VRFCoordinatorV25.TransactOpts, subId) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "recoverFunds", to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) RecoverFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RecoverFunds(&_VRFCoordinatorV25.TransactOpts, to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) RecoverFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RecoverFunds(&_VRFCoordinatorV25.TransactOpts, to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) RecoverNativeFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "recoverNativeFunds", to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) RecoverNativeFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RecoverNativeFunds(&_VRFCoordinatorV25.TransactOpts, to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) RecoverNativeFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RecoverNativeFunds(&_VRFCoordinatorV25.TransactOpts, to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "registerMigratableCoordinator", target) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorV25.TransactOpts, target) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorV25.TransactOpts, target) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) RegisterProvingKey(opts *bind.TransactOpts, oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "registerProvingKey", oracle, publicProvingKey) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) RegisterProvingKey(oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RegisterProvingKey(&_VRFCoordinatorV25.TransactOpts, oracle, publicProvingKey) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) RegisterProvingKey(oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RegisterProvingKey(&_VRFCoordinatorV25.TransactOpts, oracle, publicProvingKey) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "removeConsumer", subId, consumer) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RemoveConsumer(&_VRFCoordinatorV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RemoveConsumer(&_VRFCoordinatorV25.TransactOpts, subId, consumer) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "requestRandomWords", req) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RequestRandomWords(&_VRFCoordinatorV25.TransactOpts, req) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RequestRandomWords(&_VRFCoordinatorV25.TransactOpts, req) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subId, newOwner) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorV25.TransactOpts, subId, newOwner) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorV25.TransactOpts, subId, newOwner) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV25FeeConfig) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "setConfig", minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV25FeeConfig) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.SetConfig(&_VRFCoordinatorV25.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV25FeeConfig) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.SetConfig(&_VRFCoordinatorV25.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) SetLINKAndLINKNativeFeed(opts *bind.TransactOpts, link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "setLINKAndLINKNativeFeed", link, linkNativeFeed) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) SetLINKAndLINKNativeFeed(link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.SetLINKAndLINKNativeFeed(&_VRFCoordinatorV25.TransactOpts, link, linkNativeFeed) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) SetLINKAndLINKNativeFeed(link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.SetLINKAndLINKNativeFeed(&_VRFCoordinatorV25.TransactOpts, link, linkNativeFeed) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Transactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.contract.Transact(opts, "transferOwnership", to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Session) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.TransferOwnership(&_VRFCoordinatorV25.TransactOpts, to) +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25TransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV25.Contract.TransferOwnership(&_VRFCoordinatorV25.TransactOpts, to) +} + +type VRFCoordinatorV25ConfigSetIterator struct { + Event *VRFCoordinatorV25ConfigSet + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25ConfigSetIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25ConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25ConfigSet) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25ConfigSetIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25ConfigSetIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25ConfigSet struct { + MinimumRequestConfirmations uint16 + MaxGasLimit uint32 + StalenessSeconds uint32 + GasAfterPaymentCalculation uint32 + FallbackWeiPerUnitLink *big.Int + FeeConfig VRFCoordinatorV25FeeConfig + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorV25ConfigSetIterator, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "ConfigSet") + if err != nil { + return nil, err + } + return &VRFCoordinatorV25ConfigSetIterator{contract: _VRFCoordinatorV25.contract, event: "ConfigSet", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25ConfigSet) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorV25.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(VRFCoordinatorV25ConfigSet) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseConfigSet(log types.Log) (*VRFCoordinatorV25ConfigSet, error) { + event := new(VRFCoordinatorV25ConfigSet) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "ConfigSet", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25CoordinatorDeregisteredIterator struct { + Event *VRFCoordinatorV25CoordinatorDeregistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25CoordinatorDeregisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25CoordinatorDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25CoordinatorDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25CoordinatorDeregisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25CoordinatorDeregisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25CoordinatorDeregistered struct { + CoordinatorAddress common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorV25CoordinatorDeregisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "CoordinatorDeregistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorV25CoordinatorDeregisteredIterator{contract: _VRFCoordinatorV25.contract, event: "CoordinatorDeregistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25CoordinatorDeregistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "CoordinatorDeregistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25CoordinatorDeregistered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorV25CoordinatorDeregistered, error) { + event := new(VRFCoordinatorV25CoordinatorDeregistered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25CoordinatorRegisteredIterator struct { + Event *VRFCoordinatorV25CoordinatorRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25CoordinatorRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25CoordinatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25CoordinatorRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25CoordinatorRegisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25CoordinatorRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25CoordinatorRegistered struct { + CoordinatorAddress common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorV25CoordinatorRegisteredIterator, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "CoordinatorRegistered") + if err != nil { + return nil, err + } + return &VRFCoordinatorV25CoordinatorRegisteredIterator{contract: _VRFCoordinatorV25.contract, event: "CoordinatorRegistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25CoordinatorRegistered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "CoordinatorRegistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25CoordinatorRegistered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorV25CoordinatorRegistered, error) { + event := new(VRFCoordinatorV25CoordinatorRegistered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25FundsRecoveredIterator struct { + Event *VRFCoordinatorV25FundsRecovered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25FundsRecoveredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25FundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25FundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25FundsRecoveredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25FundsRecoveredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25FundsRecovered struct { + To common.Address + Amount *big.Int + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV25FundsRecoveredIterator, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "FundsRecovered") + if err != nil { + return nil, err + } + return &VRFCoordinatorV25FundsRecoveredIterator{contract: _VRFCoordinatorV25.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25FundsRecovered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorV25.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(VRFCoordinatorV25FundsRecovered) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseFundsRecovered(log types.Log) (*VRFCoordinatorV25FundsRecovered, error) { + event := new(VRFCoordinatorV25FundsRecovered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "FundsRecovered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25MigrationCompletedIterator struct { + Event *VRFCoordinatorV25MigrationCompleted + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25MigrationCompletedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25MigrationCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25MigrationCompleted) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25MigrationCompletedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25MigrationCompletedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25MigrationCompleted struct { + NewCoordinator common.Address + SubId *big.Int + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorV25MigrationCompletedIterator, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "MigrationCompleted") + if err != nil { + return nil, err + } + return &VRFCoordinatorV25MigrationCompletedIterator{contract: _VRFCoordinatorV25.contract, event: "MigrationCompleted", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25MigrationCompleted) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "MigrationCompleted") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25MigrationCompleted) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseMigrationCompleted(log types.Log) (*VRFCoordinatorV25MigrationCompleted, error) { + event := new(VRFCoordinatorV25MigrationCompleted) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25NativeFundsRecoveredIterator struct { + Event *VRFCoordinatorV25NativeFundsRecovered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25NativeFundsRecoveredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25NativeFundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25NativeFundsRecovered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25NativeFundsRecoveredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25NativeFundsRecoveredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25NativeFundsRecovered struct { + To common.Address + Amount *big.Int + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterNativeFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV25NativeFundsRecoveredIterator, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "NativeFundsRecovered") + if err != nil { + return nil, err + } + return &VRFCoordinatorV25NativeFundsRecoveredIterator{contract: _VRFCoordinatorV25.contract, event: "NativeFundsRecovered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchNativeFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25NativeFundsRecovered) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "NativeFundsRecovered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25NativeFundsRecovered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "NativeFundsRecovered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseNativeFundsRecovered(log types.Log) (*VRFCoordinatorV25NativeFundsRecovered, error) { + event := new(VRFCoordinatorV25NativeFundsRecovered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "NativeFundsRecovered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25OwnershipTransferRequestedIterator struct { + Event *VRFCoordinatorV25OwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25OwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25OwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25OwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25OwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25OwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV25OwnershipTransferRequestedIterator, 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 := _VRFCoordinatorV25.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25OwnershipTransferRequestedIterator{contract: _VRFCoordinatorV25.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25OwnershipTransferRequested, 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 := _VRFCoordinatorV25.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(VRFCoordinatorV25OwnershipTransferRequested) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorV25OwnershipTransferRequested, error) { + event := new(VRFCoordinatorV25OwnershipTransferRequested) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25OwnershipTransferredIterator struct { + Event *VRFCoordinatorV25OwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25OwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25OwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25OwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25OwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25OwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV25OwnershipTransferredIterator, 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 := _VRFCoordinatorV25.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25OwnershipTransferredIterator{contract: _VRFCoordinatorV25.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25OwnershipTransferred, 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 := _VRFCoordinatorV25.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(VRFCoordinatorV25OwnershipTransferred) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorV25OwnershipTransferred, error) { + event := new(VRFCoordinatorV25OwnershipTransferred) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25ProvingKeyDeregisteredIterator struct { + Event *VRFCoordinatorV25ProvingKeyDeregistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25ProvingKeyDeregisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25ProvingKeyDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25ProvingKeyDeregistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25ProvingKeyDeregisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25ProvingKeyDeregisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25ProvingKeyDeregistered struct { + KeyHash [32]byte + Oracle common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterProvingKeyDeregistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV25ProvingKeyDeregisteredIterator, error) { + + var oracleRule []interface{} + for _, oracleItem := range oracle { + oracleRule = append(oracleRule, oracleItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "ProvingKeyDeregistered", oracleRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25ProvingKeyDeregisteredIterator{contract: _VRFCoordinatorV25.contract, event: "ProvingKeyDeregistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchProvingKeyDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25ProvingKeyDeregistered, oracle []common.Address) (event.Subscription, error) { + + var oracleRule []interface{} + for _, oracleItem := range oracle { + oracleRule = append(oracleRule, oracleItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "ProvingKeyDeregistered", oracleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25ProvingKeyDeregistered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "ProvingKeyDeregistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseProvingKeyDeregistered(log types.Log) (*VRFCoordinatorV25ProvingKeyDeregistered, error) { + event := new(VRFCoordinatorV25ProvingKeyDeregistered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "ProvingKeyDeregistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25ProvingKeyRegisteredIterator struct { + Event *VRFCoordinatorV25ProvingKeyRegistered + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25ProvingKeyRegisteredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25ProvingKeyRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25ProvingKeyRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25ProvingKeyRegisteredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25ProvingKeyRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25ProvingKeyRegistered struct { + KeyHash [32]byte + Oracle common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterProvingKeyRegistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV25ProvingKeyRegisteredIterator, error) { + + var oracleRule []interface{} + for _, oracleItem := range oracle { + oracleRule = append(oracleRule, oracleItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "ProvingKeyRegistered", oracleRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25ProvingKeyRegisteredIterator{contract: _VRFCoordinatorV25.contract, event: "ProvingKeyRegistered", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25ProvingKeyRegistered, oracle []common.Address) (event.Subscription, error) { + + var oracleRule []interface{} + for _, oracleItem := range oracle { + oracleRule = append(oracleRule, oracleItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "ProvingKeyRegistered", oracleRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25ProvingKeyRegistered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "ProvingKeyRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorV25ProvingKeyRegistered, error) { + event := new(VRFCoordinatorV25ProvingKeyRegistered) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "ProvingKeyRegistered", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25RandomWordsFulfilledIterator struct { + Event *VRFCoordinatorV25RandomWordsFulfilled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25RandomWordsFulfilledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25RandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25RandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25RandomWordsFulfilledIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25RandomWordsFulfilledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25RandomWordsFulfilled struct { + RequestId *big.Int + OutputSeed *big.Int + SubId *big.Int + Payment *big.Int + Success bool + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorV25RandomWordsFulfilledIterator, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25RandomWordsFulfilledIterator{contract: _VRFCoordinatorV25.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25RandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25RandomWordsFulfilled) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorV25RandomWordsFulfilled, error) { + event := new(VRFCoordinatorV25RandomWordsFulfilled) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25RandomWordsRequestedIterator struct { + Event *VRFCoordinatorV25RandomWordsRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25RandomWordsRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25RandomWordsRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25RandomWordsRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25RandomWordsRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25RandomWordsRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25RandomWordsRequested struct { + KeyHash [32]byte + RequestId *big.Int + PreSeed *big.Int + SubId *big.Int + MinimumRequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte + Sender common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorV25RandomWordsRequestedIterator, error) { + + var keyHashRule []interface{} + for _, keyHashItem := range keyHash { + keyHashRule = append(keyHashRule, keyHashItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25RandomWordsRequestedIterator{contract: _VRFCoordinatorV25.contract, event: "RandomWordsRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25RandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) { + + var keyHashRule []interface{} + for _, keyHashItem := range keyHash { + keyHashRule = append(keyHashRule, keyHashItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25RandomWordsRequested) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorV25RandomWordsRequested, error) { + event := new(VRFCoordinatorV25RandomWordsRequested) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25SubscriptionCanceledIterator struct { + Event *VRFCoordinatorV25SubscriptionCanceled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25SubscriptionCanceledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionCanceled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25SubscriptionCanceledIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25SubscriptionCanceledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25SubscriptionCanceled struct { + SubId *big.Int + To common.Address + AmountLink *big.Int + AmountNative *big.Int + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionCanceledIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "SubscriptionCanceled", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25SubscriptionCanceledIterator{contract: _VRFCoordinatorV25.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionCanceled, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "SubscriptionCanceled", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25SubscriptionCanceled) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorV25SubscriptionCanceled, error) { + event := new(VRFCoordinatorV25SubscriptionCanceled) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25SubscriptionConsumerAddedIterator struct { + Event *VRFCoordinatorV25SubscriptionConsumerAdded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25SubscriptionConsumerAddedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionConsumerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionConsumerAdded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25SubscriptionConsumerAddedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25SubscriptionConsumerAddedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25SubscriptionConsumerAdded struct { + SubId *big.Int + Consumer common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionConsumerAddedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25SubscriptionConsumerAddedIterator{contract: _VRFCoordinatorV25.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "SubscriptionConsumerAdded", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25SubscriptionConsumerAdded) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorV25SubscriptionConsumerAdded, error) { + event := new(VRFCoordinatorV25SubscriptionConsumerAdded) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25SubscriptionConsumerRemovedIterator struct { + Event *VRFCoordinatorV25SubscriptionConsumerRemoved + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25SubscriptionConsumerRemovedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionConsumerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionConsumerRemoved) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25SubscriptionConsumerRemovedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25SubscriptionConsumerRemovedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25SubscriptionConsumerRemoved struct { + SubId *big.Int + Consumer common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionConsumerRemovedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25SubscriptionConsumerRemovedIterator{contract: _VRFCoordinatorV25.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "SubscriptionConsumerRemoved", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25SubscriptionConsumerRemoved) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorV25SubscriptionConsumerRemoved, error) { + event := new(VRFCoordinatorV25SubscriptionConsumerRemoved) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25SubscriptionCreatedIterator struct { + Event *VRFCoordinatorV25SubscriptionCreated + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25SubscriptionCreatedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionCreated) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25SubscriptionCreatedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25SubscriptionCreatedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25SubscriptionCreated struct { + SubId *big.Int + Owner common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionCreatedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "SubscriptionCreated", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25SubscriptionCreatedIterator{contract: _VRFCoordinatorV25.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionCreated, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "SubscriptionCreated", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25SubscriptionCreated) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorV25SubscriptionCreated, error) { + event := new(VRFCoordinatorV25SubscriptionCreated) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25SubscriptionFundedIterator struct { + Event *VRFCoordinatorV25SubscriptionFunded + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25SubscriptionFundedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionFunded) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25SubscriptionFundedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25SubscriptionFundedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25SubscriptionFunded struct { + SubId *big.Int + OldBalance *big.Int + NewBalance *big.Int + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionFundedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "SubscriptionFunded", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25SubscriptionFundedIterator{contract: _VRFCoordinatorV25.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionFunded, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "SubscriptionFunded", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25SubscriptionFunded) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorV25SubscriptionFunded, error) { + event := new(VRFCoordinatorV25SubscriptionFunded) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25SubscriptionFundedWithNativeIterator struct { + Event *VRFCoordinatorV25SubscriptionFundedWithNative + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25SubscriptionFundedWithNativeIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionFundedWithNative) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionFundedWithNative) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25SubscriptionFundedWithNativeIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25SubscriptionFundedWithNativeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25SubscriptionFundedWithNative struct { + SubId *big.Int + OldNativeBalance *big.Int + NewNativeBalance *big.Int + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterSubscriptionFundedWithNative(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionFundedWithNativeIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "SubscriptionFundedWithNative", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25SubscriptionFundedWithNativeIterator{contract: _VRFCoordinatorV25.contract, event: "SubscriptionFundedWithNative", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchSubscriptionFundedWithNative(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionFundedWithNative, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "SubscriptionFundedWithNative", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25SubscriptionFundedWithNative) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "SubscriptionFundedWithNative", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseSubscriptionFundedWithNative(log types.Log) (*VRFCoordinatorV25SubscriptionFundedWithNative, error) { + event := new(VRFCoordinatorV25SubscriptionFundedWithNative) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "SubscriptionFundedWithNative", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25SubscriptionOwnerTransferRequestedIterator struct { + Event *VRFCoordinatorV25SubscriptionOwnerTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25SubscriptionOwnerTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionOwnerTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionOwnerTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25SubscriptionOwnerTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25SubscriptionOwnerTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25SubscriptionOwnerTransferRequested struct { + SubId *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionOwnerTransferRequestedIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25SubscriptionOwnerTransferRequestedIterator{contract: _VRFCoordinatorV25.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25SubscriptionOwnerTransferRequested) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorV25SubscriptionOwnerTransferRequested, error) { + event := new(VRFCoordinatorV25SubscriptionOwnerTransferRequested) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFCoordinatorV25SubscriptionOwnerTransferredIterator struct { + Event *VRFCoordinatorV25SubscriptionOwnerTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV25SubscriptionOwnerTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionOwnerTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV25SubscriptionOwnerTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV25SubscriptionOwnerTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV25SubscriptionOwnerTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV25SubscriptionOwnerTransferred struct { + SubId *big.Int + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionOwnerTransferredIterator, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subIdRule) + if err != nil { + return nil, err + } + return &VRFCoordinatorV25SubscriptionOwnerTransferredIterator{contract: _VRFCoordinatorV25.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) { + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _VRFCoordinatorV25.contract.WatchLogs(opts, "SubscriptionOwnerTransferred", subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV25SubscriptionOwnerTransferred) + if err := _VRFCoordinatorV25.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 (_VRFCoordinatorV25 *VRFCoordinatorV25Filterer) ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorV25SubscriptionOwnerTransferred, error) { + event := new(VRFCoordinatorV25SubscriptionOwnerTransferred) + if err := _VRFCoordinatorV25.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetSubscription struct { + Balance *big.Int + NativeBalance *big.Int + ReqCount uint64 + Owner common.Address + Consumers []common.Address +} +type SConfig struct { + MinimumRequestConfirmations uint16 + MaxGasLimit uint32 + ReentrancyLock bool + StalenessSeconds uint32 + GasAfterPaymentCalculation uint32 +} +type SFeeConfig struct { + FulfillmentFlatFeeLinkPPM uint32 + FulfillmentFlatFeeNativePPM uint32 +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VRFCoordinatorV25.abi.Events["ConfigSet"].ID: + return _VRFCoordinatorV25.ParseConfigSet(log) + case _VRFCoordinatorV25.abi.Events["CoordinatorDeregistered"].ID: + return _VRFCoordinatorV25.ParseCoordinatorDeregistered(log) + case _VRFCoordinatorV25.abi.Events["CoordinatorRegistered"].ID: + return _VRFCoordinatorV25.ParseCoordinatorRegistered(log) + case _VRFCoordinatorV25.abi.Events["FundsRecovered"].ID: + return _VRFCoordinatorV25.ParseFundsRecovered(log) + case _VRFCoordinatorV25.abi.Events["MigrationCompleted"].ID: + return _VRFCoordinatorV25.ParseMigrationCompleted(log) + case _VRFCoordinatorV25.abi.Events["NativeFundsRecovered"].ID: + return _VRFCoordinatorV25.ParseNativeFundsRecovered(log) + case _VRFCoordinatorV25.abi.Events["OwnershipTransferRequested"].ID: + return _VRFCoordinatorV25.ParseOwnershipTransferRequested(log) + case _VRFCoordinatorV25.abi.Events["OwnershipTransferred"].ID: + return _VRFCoordinatorV25.ParseOwnershipTransferred(log) + case _VRFCoordinatorV25.abi.Events["ProvingKeyDeregistered"].ID: + return _VRFCoordinatorV25.ParseProvingKeyDeregistered(log) + case _VRFCoordinatorV25.abi.Events["ProvingKeyRegistered"].ID: + return _VRFCoordinatorV25.ParseProvingKeyRegistered(log) + case _VRFCoordinatorV25.abi.Events["RandomWordsFulfilled"].ID: + return _VRFCoordinatorV25.ParseRandomWordsFulfilled(log) + case _VRFCoordinatorV25.abi.Events["RandomWordsRequested"].ID: + return _VRFCoordinatorV25.ParseRandomWordsRequested(log) + case _VRFCoordinatorV25.abi.Events["SubscriptionCanceled"].ID: + return _VRFCoordinatorV25.ParseSubscriptionCanceled(log) + case _VRFCoordinatorV25.abi.Events["SubscriptionConsumerAdded"].ID: + return _VRFCoordinatorV25.ParseSubscriptionConsumerAdded(log) + case _VRFCoordinatorV25.abi.Events["SubscriptionConsumerRemoved"].ID: + return _VRFCoordinatorV25.ParseSubscriptionConsumerRemoved(log) + case _VRFCoordinatorV25.abi.Events["SubscriptionCreated"].ID: + return _VRFCoordinatorV25.ParseSubscriptionCreated(log) + case _VRFCoordinatorV25.abi.Events["SubscriptionFunded"].ID: + return _VRFCoordinatorV25.ParseSubscriptionFunded(log) + case _VRFCoordinatorV25.abi.Events["SubscriptionFundedWithNative"].ID: + return _VRFCoordinatorV25.ParseSubscriptionFundedWithNative(log) + case _VRFCoordinatorV25.abi.Events["SubscriptionOwnerTransferRequested"].ID: + return _VRFCoordinatorV25.ParseSubscriptionOwnerTransferRequested(log) + case _VRFCoordinatorV25.abi.Events["SubscriptionOwnerTransferred"].ID: + return _VRFCoordinatorV25.ParseSubscriptionOwnerTransferred(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VRFCoordinatorV25ConfigSet) Topic() common.Hash { + return common.HexToHash("0x777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e78") +} + +func (VRFCoordinatorV25CoordinatorDeregistered) Topic() common.Hash { + return common.HexToHash("0xf80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37") +} + +func (VRFCoordinatorV25CoordinatorRegistered) Topic() common.Hash { + return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625") +} + +func (VRFCoordinatorV25FundsRecovered) Topic() common.Hash { + return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600") +} + +func (VRFCoordinatorV25MigrationCompleted) Topic() common.Hash { + return common.HexToHash("0xd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187") +} + +func (VRFCoordinatorV25NativeFundsRecovered) Topic() common.Hash { + return common.HexToHash("0x4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c") +} + +func (VRFCoordinatorV25OwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VRFCoordinatorV25OwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VRFCoordinatorV25ProvingKeyDeregistered) Topic() common.Hash { + return common.HexToHash("0x72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d") +} + +func (VRFCoordinatorV25ProvingKeyRegistered) Topic() common.Hash { + return common.HexToHash("0xe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b8") +} + +func (VRFCoordinatorV25RandomWordsFulfilled) Topic() common.Hash { + return common.HexToHash("0x49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa7") +} + +func (VRFCoordinatorV25RandomWordsRequested) Topic() common.Hash { + return common.HexToHash("0xeb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e") +} + +func (VRFCoordinatorV25SubscriptionCanceled) Topic() common.Hash { + return common.HexToHash("0x8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4") +} + +func (VRFCoordinatorV25SubscriptionConsumerAdded) Topic() common.Hash { + return common.HexToHash("0x1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1") +} + +func (VRFCoordinatorV25SubscriptionConsumerRemoved) Topic() common.Hash { + return common.HexToHash("0x32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7") +} + +func (VRFCoordinatorV25SubscriptionCreated) Topic() common.Hash { + return common.HexToHash("0x1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d") +} + +func (VRFCoordinatorV25SubscriptionFunded) Topic() common.Hash { + return common.HexToHash("0x1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a") +} + +func (VRFCoordinatorV25SubscriptionFundedWithNative) Topic() common.Hash { + return common.HexToHash("0x7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902") +} + +func (VRFCoordinatorV25SubscriptionOwnerTransferRequested) Topic() common.Hash { + return common.HexToHash("0x21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1") +} + +func (VRFCoordinatorV25SubscriptionOwnerTransferred) Topic() common.Hash { + return common.HexToHash("0xd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386") +} + +func (_VRFCoordinatorV25 *VRFCoordinatorV25) Address() common.Address { + return _VRFCoordinatorV25.address +} + +type VRFCoordinatorV25Interface interface { + BLOCKHASHSTORE(opts *bind.CallOpts) (common.Address, error) + + LINK(opts *bind.CallOpts) (common.Address, error) + + LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) + + MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) + + MAXNUMWORDS(opts *bind.CallOpts) (uint32, error) + + 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, + + error) + + HashOfKey(opts *bind.CallOpts, publicKey [2]*big.Int) ([32]byte, error) + + MigrationVersion(opts *bind.CallOpts) (uint8, error) + + Owner(opts *bind.CallOpts) (common.Address, error) + + PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) + + SConfig(opts *bind.CallOpts) (SConfig, + + error) + + SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) + + SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) + + SFeeConfig(opts *bind.CallOpts) (SFeeConfig, + + error) + + SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (common.Address, error) + + SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + + STotalBalance(opts *bind.CallOpts) (*big.Int, error) + + STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) + + CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) + + CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) + + DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) + + DeregisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) + + FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV25RequestCommitment) (*types.Transaction, error) + + FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator 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) + + OracleWithdrawNative(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) + + OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + RecoverNativeFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) + + RegisterProvingKey(opts *bind.TransactOpts, oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) + + RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) + + RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) + + RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) + + SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV25FeeConfig) (*types.Transaction, error) + + SetLINKAndLINKNativeFeed(opts *bind.TransactOpts, link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorV25ConfigSetIterator, error) + + WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25ConfigSet) (event.Subscription, error) + + ParseConfigSet(log types.Log) (*VRFCoordinatorV25ConfigSet, error) + + FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorV25CoordinatorDeregisteredIterator, error) + + WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25CoordinatorDeregistered) (event.Subscription, error) + + ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorV25CoordinatorDeregistered, error) + + FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorV25CoordinatorRegisteredIterator, error) + + WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25CoordinatorRegistered) (event.Subscription, error) + + ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorV25CoordinatorRegistered, error) + + FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV25FundsRecoveredIterator, error) + + WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25FundsRecovered) (event.Subscription, error) + + ParseFundsRecovered(log types.Log) (*VRFCoordinatorV25FundsRecovered, error) + + FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorV25MigrationCompletedIterator, error) + + WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25MigrationCompleted) (event.Subscription, error) + + ParseMigrationCompleted(log types.Log) (*VRFCoordinatorV25MigrationCompleted, error) + + FilterNativeFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV25NativeFundsRecoveredIterator, error) + + WatchNativeFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25NativeFundsRecovered) (event.Subscription, error) + + ParseNativeFundsRecovered(log types.Log) (*VRFCoordinatorV25NativeFundsRecovered, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV25OwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25OwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorV25OwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV25OwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25OwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorV25OwnershipTransferred, error) + + FilterProvingKeyDeregistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV25ProvingKeyDeregisteredIterator, error) + + WatchProvingKeyDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25ProvingKeyDeregistered, oracle []common.Address) (event.Subscription, error) + + ParseProvingKeyDeregistered(log types.Log) (*VRFCoordinatorV25ProvingKeyDeregistered, error) + + FilterProvingKeyRegistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV25ProvingKeyRegisteredIterator, error) + + WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25ProvingKeyRegistered, oracle []common.Address) (event.Subscription, error) + + ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorV25ProvingKeyRegistered, error) + + FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorV25RandomWordsFulfilledIterator, error) + + WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25RandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) + + ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorV25RandomWordsFulfilled, error) + + FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorV25RandomWordsRequestedIterator, error) + + WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25RandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) + + ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorV25RandomWordsRequested, error) + + FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionCanceledIterator, error) + + WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionCanceled, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorV25SubscriptionCanceled, error) + + FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionConsumerAddedIterator, error) + + WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorV25SubscriptionConsumerAdded, error) + + FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionConsumerRemovedIterator, error) + + WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorV25SubscriptionConsumerRemoved, error) + + FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionCreatedIterator, error) + + WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionCreated, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorV25SubscriptionCreated, error) + + FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionFundedIterator, error) + + WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionFunded, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorV25SubscriptionFunded, error) + + FilterSubscriptionFundedWithNative(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionFundedWithNativeIterator, error) + + WatchSubscriptionFundedWithNative(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionFundedWithNative, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionFundedWithNative(log types.Log) (*VRFCoordinatorV25SubscriptionFundedWithNative, error) + + FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionOwnerTransferRequestedIterator, error) + + WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorV25SubscriptionOwnerTransferRequested, error) + + FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV25SubscriptionOwnerTransferredIterator, error) + + WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV25SubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) + + ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorV25SubscriptionOwnerTransferred, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} 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 index 6824b91891..dd7865fe8a 100644 --- 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 @@ -38,8 +38,8 @@ type VRFV2PlusClientRandomWordsRequest struct { } 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\":[],\"name\":\"SubscriptionIDCollisionFound\",\"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: "0x6080604052600060035534801561001557600080fd5b50604051610fc6380380610fc683398101604081905261003491610081565b600580546001600160a01b039384166001600160a01b031991821617909155600480549290931691161790556100b4565b80516001600160a01b038116811461007c57600080fd5b919050565b6000806040838503121561009457600080fd5b61009d83610065565b91506100ab60208401610065565b90509250929050565b610f03806100c36000396000f3fe6080604052600436106100c75760003560e01c8063ce3f471911610074578063dc311dd31161004e578063dc311dd314610325578063e89e106a14610355578063ed8b558f1461036b57600080fd5b8063ce3f4719146102c3578063d6100d1c146102d8578063da4f5e6d146102f857600080fd5b806386175f58116100a557806386175f581461022557806393f3acb6146102685780639b1c385e1461029557600080fd5b80630495f265146100cc578063086597b31461018157806318e3dd27146101d3575b600080fd5b3480156100d857600080fd5b5061013b6100e7366004610ce7565b6000602081905290815260409020805460029091015473ffffffffffffffffffffffffffffffffffffffff909116906bffffffffffffffffffffffff808216916c0100000000000000000000000090041683565b6040805173ffffffffffffffffffffffffffffffffffffffff90941684526bffffffffffffffffffffffff92831660208501529116908201526060015b60405180910390f35b34801561018d57600080fd5b506004546101ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610178565b3480156101df57600080fd5b50600254610208906c0100000000000000000000000090046bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610178565b34801561023157600080fd5b506101ae610240366004610ce7565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561027457600080fd5b50610288610283366004610ce7565b610390565b6040516101789190610dc4565b3480156102a157600080fd5b506102b56102b0366004610be2565b61043b565b604051908152602001610178565b6102d66102d1366004610b70565b61044c565b005b3480156102e457600080fd5b506102d66102f3366004610ce7565b6107a7565b34801561030457600080fd5b506005546101ae9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561033157600080fd5b50610345610340366004610ce7565b61082f565b6040516101789493929190610d3b565b34801561036157600080fd5b506102b560035481565b34801561037757600080fd5b50600254610208906bffffffffffffffffffffffff1681565b6040805160018082528183019092526060916000919060208083019080368337019050509050826040516020016103fe918152604060208201819052600a908201527f6e6f742072616e646f6d00000000000000000000000000000000000000000000606082015260800190565b6040516020818303038152906040528051906020012060001c8160008151811061042a5761042a610e98565b602090810291909101015292915050565b60006104463361095a565b92915050565b60045473ffffffffffffffffffffffffffffffffffffffff1633146104c557600480546040517ff5828f73000000000000000000000000000000000000000000000000000000008152339281019290925273ffffffffffffffffffffffffffffffffffffffff1660248201526044015b60405180910390fd5b60006104d382840184610c24565b9050806000015160ff166001146105255780516040517f8df4607c00000000000000000000000000000000000000000000000000000000815260ff9091166004820152600160248201526044016104bc565b8060a001516bffffffffffffffffffffffff16341461058c5760a08101516040517f6acf13500000000000000000000000000000000000000000000000000000000081523460048201526bffffffffffffffffffffffff90911660248201526044016104bc565b602080820151600090815290819052604090205473ffffffffffffffffffffffffffffffffffffffff16156105ed576040517f4d5f486a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051608080820183528383015173ffffffffffffffffffffffffffffffffffffffff90811683526060808601516020808601918252938701516bffffffffffffffffffffffff9081168688015260a0880151169185019190915282860151600090815280845294909420835181547fffffffffffffffffffffffff00000000000000000000000000000000000000001692169190911781559251805192939261069e92600185019201906109c6565b506040820151600291820180546060909401516bffffffffffffffffffffffff9283167fffffffffffffffff000000000000000000000000000000000000000000000000909516949094176c01000000000000000000000000948316850217905560a084015182549093600c92610719928692900416610e39565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508060800151600260008282829054906101000a90046bffffffffffffffffffffffff166107749190610e39565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b60008181526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1680631fe543e3836107dc81610390565b6040518363ffffffff1660e01b81526004016107f9929190610dd7565b600060405180830381600087803b15801561081357600080fd5b505af1158015610827573d6000803e3d6000fd5b505050505050565b6000818152602081905260408120546060908290819073ffffffffffffffffffffffffffffffffffffffff16610891576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008581526020818152604091829020805460028201546001909201805485518186028101860190965280865273ffffffffffffffffffffffffffffffffffffffff9092169490936bffffffffffffffffffffffff808516946c0100000000000000000000000090041692859183018282801561094457602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610919575b5050505050925093509350935093509193509193565b6000600354600161096b9190610e21565b6003819055600081815260016020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94909416939093179092555090565b828054828255906000526020600020908101928215610a40579160200282015b82811115610a4057825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9091161782556020909201916001909101906109e6565b50610a4c929150610a50565b5090565b5b80821115610a4c5760008155600101610a51565b803573ffffffffffffffffffffffffffffffffffffffff81168114610a8957600080fd5b919050565b600082601f830112610a9f57600080fd5b8135602067ffffffffffffffff80831115610abc57610abc610ec7565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715610aff57610aff610ec7565b60405284815283810192508684018288018501891015610b1e57600080fd5b600092505b85831015610b4857610b3481610a65565b845292840192600192909201918401610b23565b50979650505050505050565b80356bffffffffffffffffffffffff81168114610a8957600080fd5b60008060208385031215610b8357600080fd5b823567ffffffffffffffff80821115610b9b57600080fd5b818501915085601f830112610baf57600080fd5b813581811115610bbe57600080fd5b866020828501011115610bd057600080fd5b60209290920196919550909350505050565b600060208284031215610bf457600080fd5b813567ffffffffffffffff811115610c0b57600080fd5b820160c08185031215610c1d57600080fd5b9392505050565b600060208284031215610c3657600080fd5b813567ffffffffffffffff80821115610c4e57600080fd5b9083019060c08286031215610c6257600080fd5b610c6a610df8565b823560ff81168114610c7b57600080fd5b815260208381013590820152610c9360408401610a65565b6040820152606083013582811115610caa57600080fd5b610cb687828601610a8e565b606083015250610cc860808401610b54565b6080820152610cd960a08401610b54565b60a082015295945050505050565b600060208284031215610cf957600080fd5b5035919050565b600081518084526020808501945080840160005b83811015610d3057815187529582019590820190600101610d14565b509495945050505050565b60006080820173ffffffffffffffffffffffffffffffffffffffff8088168452602060808186015282885180855260a087019150828a01945060005b81811015610d95578551851683529483019491830191600101610d77565b50506bffffffffffffffffffffffff978816604087015295909616606090940193909352509195945050505050565b602081526000610c1d6020830184610d00565b828152604060208201526000610df06040830184610d00565b949350505050565b60405160c0810167ffffffffffffffff81118282101715610e1b57610e1b610ec7565b60405290565b60008219821115610e3457610e34610e69565b500190565b60006bffffffffffffffffffffffff808316818516808303821115610e6057610e60610e69565b01949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", + 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\":[],\"name\":\"SubscriptionIDCollisionFound\",\"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\":\"uint96\",\"name\":\"linkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"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\":\"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\":\"req\",\"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\":\"uint96\",\"name\":\"linkBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"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: "0x6080604052600060035534801561001557600080fd5b506040516111d73803806111d783398101604081905261003491610081565b600580546001600160a01b039384166001600160a01b031991821617909155600480549290931691161790556100b4565b80516001600160a01b038116811461007c57600080fd5b919050565b6000806040838503121561009457600080fd5b61009d83610065565b91506100ab60208401610065565b90509250929050565b611114806100c36000396000f3fe6080604052600436106100c75760003560e01c8063ce3f471911610074578063dc311dd31161004e578063dc311dd314610361578063e89e106a14610392578063ed8b558f146103a857600080fd5b8063ce3f4719146102ff578063d6100d1c14610314578063da4f5e6d1461033457600080fd5b806386175f58116100a557806386175f581461026157806393f3acb6146102a45780639b1c385e146102d157600080fd5b80630495f265146100cc578063086597b3146101bd57806318e3dd271461020f575b600080fd5b3480156100d857600080fd5b506101636100e7366004610ec8565b600060208190529081526040902080546001909101546bffffffffffffffffffffffff808316926c01000000000000000000000000810490911691780100000000000000000000000000000000000000000000000090910467ffffffffffffffff169073ffffffffffffffffffffffffffffffffffffffff1684565b604080516bffffffffffffffffffffffff958616815294909316602085015267ffffffffffffffff9091169183019190915273ffffffffffffffffffffffffffffffffffffffff1660608201526080015b60405180910390f35b3480156101c957600080fd5b506004546101ea9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101b4565b34801561021b57600080fd5b50600254610244906c0100000000000000000000000090046bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff90911681526020016101b4565b34801561026d57600080fd5b506101ea61027c366004610ec8565b60016020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156102b057600080fd5b506102c46102bf366004610ec8565b6103cd565b6040516101b49190610f1c565b3480156102dd57600080fd5b506102f16102ec366004610dca565b610478565b6040519081526020016101b4565b61031261030d366004610d58565b6105aa565b005b34801561032057600080fd5b5061031261032f366004610ec8565b61095e565b34801561034057600080fd5b506005546101ea9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561036d57600080fd5b5061038161037c366004610ec8565b6109e6565b6040516101b4959493929190610f50565b34801561039e57600080fd5b506102f160035481565b3480156103b457600080fd5b50600254610244906bffffffffffffffffffffffff1681565b60408051600180825281830190925260609160009190602080830190803683370190505090508260405160200161043b918152604060208201819052600a908201527f6e6f742072616e646f6d00000000000000000000000000000000000000000000606082015260800190565b6040516020818303038152906040528051906020012060001c81600081518110610467576104676110a9565b602090810291909101015292915050565b60208181013560009081528082526040808220815160a08101835281546bffffffffffffffffffffffff80821683526c01000000000000000000000000820416828701527801000000000000000000000000000000000000000000000000900467ffffffffffffffff1681840152600182015473ffffffffffffffffffffffffffffffffffffffff166060820152600282018054845181880281018801909552808552949586959294608086019390929183018282801561056f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610544575b50505050508152505090508060400151600161058b919061102b565b67ffffffffffffffff1660408201526105a333610b42565b9392505050565b60045473ffffffffffffffffffffffffffffffffffffffff16331461062357600480546040517ff5828f73000000000000000000000000000000000000000000000000000000008152339281019290925273ffffffffffffffffffffffffffffffffffffffff1660248201526044015b60405180910390fd5b600061063182840184610e05565b9050806000015160ff166001146106835780516040517f8df4607c00000000000000000000000000000000000000000000000000000000815260ff90911660048201526001602482015260440161061a565b8060a001516bffffffffffffffffffffffff1634146106ea5760a08101516040517f6acf13500000000000000000000000000000000000000000000000000000000081523460048201526bffffffffffffffffffffffff909116602482015260440161061a565b602080820151600090815290819052604090206001015473ffffffffffffffffffffffffffffffffffffffff161561074e576040517f4d5f486a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160a080820183526080808501516bffffffffffffffffffffffff9081168452918501518216602080850191825260008587018181528888015173ffffffffffffffffffffffffffffffffffffffff9081166060808a019182528b0151968901968752848b0151845283855298909220875181549551925167ffffffffffffffff1678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff9389166c01000000000000000000000000027fffffffffffffffff000000000000000000000000000000000000000000000000909716919098161794909417169490941782559451600182018054919094167fffffffffffffffffffffffff000000000000000000000000000000000000000090911617909255518051929391926108989260028501920190610bae565b50505060a081015160028054600c906108d09084906c0100000000000000000000000090046bffffffffffffffffffffffff16611057565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff1602179055508060800151600260008282829054906101000a90046bffffffffffffffffffffffff1661092b9190611057565b92506101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550505050565b60008181526001602052604090205473ffffffffffffffffffffffffffffffffffffffff1680631fe543e383610993816103cd565b6040518363ffffffff1660e01b81526004016109b0929190610f2f565b600060405180830381600087803b1580156109ca57600080fd5b505af11580156109de573d6000803e3d6000fd5b505050505050565b60008181526020819052604081206001015481908190819060609073ffffffffffffffffffffffffffffffffffffffff16610a4d576040517f1f6a65b600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000868152602081815260409182902080546001820154600290920180548551818602810186019096528086526bffffffffffffffffffffffff808416966c01000000000000000000000000850490911695780100000000000000000000000000000000000000000000000090940467ffffffffffffffff169473ffffffffffffffffffffffffffffffffffffffff169390918391830182828015610b2857602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610afd575b505050505090509450945094509450945091939590929450565b60006003546001610b539190611013565b6003819055600081815260016020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff94909416939093179092555090565b828054828255906000526020600020908101928215610c28579160200282015b82811115610c2857825182547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909116178255602090920191600190910190610bce565b50610c34929150610c38565b5090565b5b80821115610c345760008155600101610c39565b803573ffffffffffffffffffffffffffffffffffffffff81168114610c7157600080fd5b919050565b600082601f830112610c8757600080fd5b8135602067ffffffffffffffff80831115610ca457610ca46110d8565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715610ce757610ce76110d8565b60405284815283810192508684018288018501891015610d0657600080fd5b600092505b85831015610d3057610d1c81610c4d565b845292840192600192909201918401610d0b565b50979650505050505050565b80356bffffffffffffffffffffffff81168114610c7157600080fd5b60008060208385031215610d6b57600080fd5b823567ffffffffffffffff80821115610d8357600080fd5b818501915085601f830112610d9757600080fd5b813581811115610da657600080fd5b866020828501011115610db857600080fd5b60209290920196919550909350505050565b600060208284031215610ddc57600080fd5b813567ffffffffffffffff811115610df357600080fd5b820160c081850312156105a357600080fd5b600060208284031215610e1757600080fd5b813567ffffffffffffffff80821115610e2f57600080fd5b9083019060c08286031215610e4357600080fd5b610e4b610fea565b823560ff81168114610e5c57600080fd5b815260208381013590820152610e7460408401610c4d565b6040820152606083013582811115610e8b57600080fd5b610e9787828601610c76565b606083015250610ea960808401610d3c565b6080820152610eba60a08401610d3c565b60a082015295945050505050565b600060208284031215610eda57600080fd5b5035919050565b600081518084526020808501945080840160005b83811015610f1157815187529582019590820190600101610ef5565b509495945050505050565b6020815260006105a36020830184610ee1565b828152604060208201526000610f486040830184610ee1565b949350505050565b600060a082016bffffffffffffffffffffffff808916845260208189168186015267ffffffffffffffff8816604086015273ffffffffffffffffffffffffffffffffffffffff9150818716606086015260a0608086015282865180855260c087019150828801945060005b81811015610fd9578551851683529483019491830191600101610fbb565b50909b9a5050505050505050505050565b60405160c0810167ffffffffffffffff8111828210171561100d5761100d6110d8565b60405290565b600082198211156110265761102661107a565b500190565b600067ffffffffffffffff80831681851680830382111561104e5761104e61107a565b01949350505050565b60006bffffffffffffffffffffffff80831681851680830382111561104e5761104e5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var VRFCoordinatorV2PlusV2ExampleABI = VRFCoordinatorV2PlusV2ExampleMetaData.ABI @@ -211,10 +211,11 @@ func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) GetSu 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) + outstruct.LinkBalance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.NativeBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + 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 @@ -331,9 +332,10 @@ func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleCaller) SSubs 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) + outstruct.LinkBalance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.NativeBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.ReqCount = *abi.ConvertType(out[2], new(uint64)).(*uint64) + outstruct.Owner = *abi.ConvertType(out[3], new(common.Address)).(*common.Address) return *outstruct, err @@ -419,28 +421,30 @@ func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactorSes 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 *VRFCoordinatorV2PlusV2ExampleTransactor) RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.contract.Transact(opts, "requestRandomWords", req) } -func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) RequestRandomWords(arg0 VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusV2Example.Contract.RequestRandomWords(&_VRFCoordinatorV2PlusV2Example.TransactOpts, arg0) +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.RequestRandomWords(&_VRFCoordinatorV2PlusV2Example.TransactOpts, req) } -func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactorSession) RequestRandomWords(arg0 VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusV2Example.Contract.RequestRandomWords(&_VRFCoordinatorV2PlusV2Example.TransactOpts, arg0) +func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2ExampleTransactorSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusV2Example.Contract.RequestRandomWords(&_VRFCoordinatorV2PlusV2Example.TransactOpts, req) } type GetSubscription struct { - Owner common.Address - Consumers []common.Address LinkBalance *big.Int NativeBalance *big.Int + ReqCount uint64 + Owner common.Address + Consumers []common.Address } type SSubscriptions struct { - Owner common.Address LinkBalance *big.Int NativeBalance *big.Int + ReqCount uint64 + Owner common.Address } func (_VRFCoordinatorV2PlusV2Example *VRFCoordinatorV2PlusV2Example) Address() common.Address { @@ -474,7 +478,7 @@ type VRFCoordinatorV2PlusV2ExampleInterface interface { OnMigration(opts *bind.TransactOpts, encodedData []byte) (*types.Transaction, error) - RequestRandomWords(opts *bind.TransactOpts, arg0 VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) + RequestRandomWords(opts *bind.TransactOpts, req 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 deleted file mode 100644 index a57ed02b81..0000000000 --- a/core/gethwrappers/generated/vrf_coordinator_v2plus/vrf_coordinator_v2plus.go +++ /dev/null @@ -1,3950 +0,0 @@ -// Code generated - DO NOT EDIT. -// This file is a generated binding and any manual changes will be lost. - -package vrf_coordinator_v2plus - -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 VRFCoordinatorV2PlusFeeConfig struct { - FulfillmentFlatFeeLinkPPM uint32 - FulfillmentFlatFeeEthPPM uint32 -} - -type VRFCoordinatorV2PlusRequestCommitment struct { - BlockNum uint64 - SubId *big.Int - CallbackGasLimit uint32 - NumWords uint32 - Sender common.Address - ExtraArgs []byte -} - -type VRFProof struct { - Pk [2]*big.Int - Gamma [2]*big.Int - C *big.Int - S *big.Int - Seed *big.Int - UWitness common.Address - CGammaWitness [2]*big.Int - SHashWitness [2]*big.Int - ZInv *big.Int -} - -type VRFV2PlusClientRandomWordsRequest struct { - KeyHash [32]byte - SubId *big.Int - RequestConfirmations uint16 - CallbackGasLimit uint32 - NumWords uint32 - ExtraArgs []byte -} - -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\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"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\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"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: "0x60a06040523480156200001157600080fd5b506040516200615938038062006159833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615f7e620001db600039600081816105ee0152613a860152615f7e6000f3fe6080604052600436106102dc5760003560e01c80638da5cb5b1161017f578063bec4c08c116100e1578063dc311dd31161008a578063e95704bd11610064578063e95704bd1461095d578063ee9d2d3814610984578063f2fde38b146109b157600080fd5b8063dc311dd3146108f9578063e72f6e301461092a578063e8509bff1461094a57600080fd5b8063d98e620e116100bb578063d98e620e14610883578063da2f2610146108a3578063dac83d29146108d957600080fd5b8063bec4c08c14610823578063caf70c4a14610843578063cb6317971461086357600080fd5b8063a8cb447b11610143578063aefb212f1161011d578063aefb212f146107b6578063b08c8795146107e3578063b2a7cac51461080357600080fd5b8063a8cb447b14610756578063aa433aff14610776578063ad1783611461079657600080fd5b80638da5cb5b146106ab5780639b1c385e146106c95780639d40a6fd146106e9578063a21a23e414610721578063a4c0ed361461073657600080fd5b806340d6bb821161024357806366316d8d116101ec5780636f64f03f116101c65780636f64f03f1461065657806379ba50971461067657806386fe91c71461068b57600080fd5b806366316d8d146105bc578063689c4517146105dc5780636b6feccc1461061057600080fd5b806357133e641161021d57806357133e64146105675780635d06b4ab1461058757806364d51a2a146105a757600080fd5b806340d6bb82146104ec57806341af6c871461051757806346d8d4861461054757600080fd5b80630ae09540116102a5578063294daa491161027f578063294daa4914610478578063330987b314610494578063405b84fa146104cc57600080fd5b80630ae09540146103f857806315c48b84146104185780631b6b6d231461044057600080fd5b8062012291146102e157806304104edb1461030e578063043bd6ae14610330578063088070f51461035457806308821d58146103d8575b600080fd5b3480156102ed57600080fd5b506102f66109d1565b60405161030593929190615ae2565b60405180910390f35b34801561031a57600080fd5b5061032e61032936600461542f565b610a4d565b005b34801561033c57600080fd5b5061034660115481565b604051908152602001610305565b34801561036057600080fd5b50600d546103a09061ffff81169063ffffffff62010000820481169160ff600160301b820416916701000000000000008204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a001610305565b3480156103e457600080fd5b5061032e6103f336600461556f565b610c0f565b34801561040457600080fd5b5061032e610413366004615811565b610da3565b34801561042457600080fd5b5061042d60c881565b60405161ffff9091168152602001610305565b34801561044c57600080fd5b50600254610460906001600160a01b031681565b6040516001600160a01b039091168152602001610305565b34801561048457600080fd5b5060405160018152602001610305565b3480156104a057600080fd5b506104b46104af366004615641565b610e71565b6040516001600160601b039091168152602001610305565b3480156104d857600080fd5b5061032e6104e7366004615811565b61135b565b3480156104f857600080fd5b506105026101f481565b60405163ffffffff9091168152602001610305565b34801561052357600080fd5b506105376105323660046155c4565b611782565b6040519015158152602001610305565b34801561055357600080fd5b5061032e61056236600461544c565b611983565b34801561057357600080fd5b5061032e610582366004615481565b611b00565b34801561059357600080fd5b5061032e6105a236600461542f565b611b60565b3480156105b357600080fd5b5061042d606481565b3480156105c857600080fd5b5061032e6105d736600461544c565b611c1e565b3480156105e857600080fd5b506104607f000000000000000000000000000000000000000000000000000000000000000081565b34801561061c57600080fd5b506012546106399063ffffffff8082169164010000000090041682565b6040805163ffffffff938416815292909116602083015201610305565b34801561066257600080fd5b5061032e6106713660046154ba565b611de6565b34801561068257600080fd5b5061032e611ee5565b34801561069757600080fd5b50600a546104b4906001600160601b031681565b3480156106b757600080fd5b506000546001600160a01b0316610460565b3480156106d557600080fd5b506103466106e436600461571e565b611f96565b3480156106f557600080fd5b50600754610709906001600160401b031681565b6040516001600160401b039091168152602001610305565b34801561072d57600080fd5b5061034661238b565b34801561074257600080fd5b5061032e6107513660046154e7565b6125db565b34801561076257600080fd5b5061032e61077136600461542f565b61277b565b34801561078257600080fd5b5061032e6107913660046155c4565b612896565b3480156107a257600080fd5b50600354610460906001600160a01b031681565b3480156107c257600080fd5b506107d66107d1366004615836565b6128f6565b6040516103059190615a47565b3480156107ef57600080fd5b5061032e6107fe366004615773565b6129f7565b34801561080f57600080fd5b5061032e61081e3660046155c4565b612b8b565b34801561082f57600080fd5b5061032e61083e366004615811565b612cc1565b34801561084f57600080fd5b5061034661085e36600461558b565b612e5d565b34801561086f57600080fd5b5061032e61087e366004615811565b612e8d565b34801561088f57600080fd5b5061034661089e3660046155c4565b613190565b3480156108af57600080fd5b506104606108be3660046155c4565b600e602052600090815260409020546001600160a01b031681565b3480156108e557600080fd5b5061032e6108f4366004615811565b6131b1565b34801561090557600080fd5b506109196109143660046155c4565b6132d0565b604051610305959493929190615c4a565b34801561093657600080fd5b5061032e61094536600461542f565b6133cb565b61032e6109583660046155c4565b6135b3565b34801561096957600080fd5b50600a546104b490600160601b90046001600160601b031681565b34801561099057600080fd5b5061034661099f3660046155c4565b60106020526000908152604090205481565b3480156109bd57600080fd5b5061032e6109cc36600461542f565b6136f2565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff16939192839190830182828015610a3b57602002820191906000526020600020905b815481526020019060010190808311610a27575b50505050509050925092509250909192565b610a55613703565b60135460005b81811015610be257826001600160a01b031660138281548110610a8057610a80615f22565b6000918252602090912001546001600160a01b03161415610bd0576013610aa8600184615e1b565b81548110610ab857610ab8615f22565b600091825260209091200154601380546001600160a01b039092169183908110610ae457610ae4615f22565b600091825260209091200180546001600160a01b0319166001600160a01b0392909216919091179055826013610b1b600185615e1b565b81548110610b2b57610b2b615f22565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506013805480610b6a57610b6a615f0c565b6000828152602090819020600019908301810180546001600160a01b03191690559091019091556040516001600160a01b03851681527ff80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37910160405180910390a1505050565b80610bda81615e8a565b915050610a5b565b50604051635428d44960e01b81526001600160a01b03831660048201526024015b60405180910390fd5b50565b610c17613703565b604080518082018252600091610c46919084906002908390839080828437600092019190915250612e5d915050565b6000818152600e60205260409020549091506001600160a01b031680610c8257604051631dfd6e1360e21b815260048101839052602401610c03565b6000828152600e6020526040812080546001600160a01b03191690555b600f54811015610d5a5782600f8281548110610cbd57610cbd615f22565b90600052602060002001541415610d4857600f805460009190610ce290600190615e1b565b81548110610cf257610cf2615f22565b9060005260206000200154905080600f8381548110610d1357610d13615f22565b600091825260209091200155600f805480610d3057610d30615f0c565b60019003818190600052602060002001600090559055505b80610d5281615e8a565b915050610c9f565b50806001600160a01b03167f72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d83604051610d9691815260200190565b60405180910390a2505050565b60008281526005602052604090205482906001600160a01b031680610ddb57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614610e0f57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615610e3a5760405163769dd35360e11b815260040160405180910390fd5b610e4384611782565b15610e6157604051631685ecdd60e31b815260040160405180910390fd5b610e6b848461375f565b50505050565b600d54600090600160301b900460ff1615610e9f5760405163769dd35360e11b815260040160405180910390fd5b60005a90506000610eb0858561391b565b90506000846060015163ffffffff166001600160401b03811115610ed657610ed6615f38565b604051908082528060200260200182016040528015610eff578160200160208202803683370190505b50905060005b856060015163ffffffff16811015610f7f57826040015181604051602001610f37929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c828281518110610f6257610f62615f22565b602090810291909101015280610f7781615e8a565b915050610f05565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b91610fb791908690602401615b55565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805466ff0000000000001916600160301b17905590880151608089015191925060009161101f9163ffffffff169084613ba8565b600d805466ff00000000000019169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b0316611062816001615d9b565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a015180516110af90600190615e1b565b815181106110bf576110bf615f22565b602091010151600d5460f89190911c60011491506000906110f0908a90600160581b900463ffffffff163a85613bf6565b905081156111f9576020808c01516000908152600690915260409020546001600160601b03808316600160601b90920416101561114057604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c90611177908490600160601b90046001600160601b0316615e32565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c9091528120805485945090926111d091859116615dc6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506112e5565b6020808c01516000908152600690915260409020546001600160601b038083169116101561123a57604051631e9acf1760e31b815260040160405180910390fd5b6020808c0151600090815260069091526040812080548392906112679084906001600160601b0316615e32565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b9091528120805485945090926112c091859116615dc6565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051611342939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b600d54600160301b900460ff16156113865760405163769dd35360e11b815260040160405180910390fd5b61138f81613c46565b6113b757604051635428d44960e01b81526001600160a01b0382166004820152602401610c03565b6000806000806113c6866132d0565b945094505093509350336001600160a01b0316826001600160a01b0316146114305760405162461bcd60e51b815260206004820152601660248201527f4e6f7420737562736372697074696f6e206f776e6572000000000000000000006044820152606401610c03565b61143986611782565b156114865760405162461bcd60e51b815260206004820152601660248201527f50656e64696e67207265717565737420657869737473000000000000000000006044820152606401610c03565b60006040518060c0016040528061149b600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016114ef9190615a6d565b604051602081830303815290604052905061150988613cb0565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b03881690611542908590600401615a5a565b6000604051808303818588803b15801561155b57600080fd5b505af115801561156f573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150611598905057506001600160601b03861615155b156116775760025460405163a9059cbb60e01b81526001600160a01b0389811660048301526001600160601b03891660248301529091169063a9059cbb90604401602060405180830381600087803b1580156115f357600080fd5b505af1158015611607573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061162b91906155a7565b6116775760405162461bcd60e51b815260206004820152601260248201527f696e73756666696369656e742066756e647300000000000000000000000000006044820152606401610c03565b600d805466ff0000000000001916600160301b17905560005b8351811015611725578381815181106116ab576116ab615f22565b6020908102919091010151604051638ea9811760e01b81526001600160a01b038a8116600483015290911690638ea9811790602401600060405180830381600087803b1580156116fa57600080fd5b505af115801561170e573d6000803e3d6000fd5b50505050808061171d90615e8a565b915050611690565b50600d805466ff00000000000019169055604080516001600160a01b0389168152602081018a90527fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187910160405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561180c57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116117ee575b505050505081525050905060005b8160400151518110156119795760005b600f5481101561196657600061192f600f838154811061184c5761184c615f22565b90600052602060002001548560400151858151811061186d5761186d615f22565b602002602001015188600460008960400151898151811061189057611890615f22565b6020908102919091018101516001600160a01b03908116835282820193909352604091820160009081208e82528252829020548251808301889052959093168583015260608501939093526001600160401b039091166080808501919091528151808503909101815260a08401825280519083012060c084019490945260e0808401859052815180850390910181526101009093019052815191012091565b50600081815260106020526040902054909150156119535750600195945050505050565b508061195e81615e8a565b91505061182a565b508061197181615e8a565b91505061181a565b5060009392505050565b600d54600160301b900460ff16156119ae5760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b03808316911610156119ea57604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c602052604081208054839290611a129084906001600160601b0316615e32565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316611a5a9190615e32565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114611ad4576040519150601f19603f3d011682016040523d82523d6000602084013e611ad9565b606091505b5050905080611afb57604051630dcf35db60e41b815260040160405180910390fd5b505050565b611b08613703565b6002546001600160a01b031615611b3257604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b611b68613703565b611b7181613c46565b15611b9a5760405163ac8a27ef60e01b81526001600160a01b0382166004820152602401610c03565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383169081179091556040519081527fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af016259060200160405180910390a150565b600d54600160301b900460ff1615611c495760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b0316611c725760405163c1f0c0a160e01b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b0380831691161015611cae57604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b602052604081208054839290611cd69084906001600160601b0316615e32565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b0316611d1e9190615e32565b82546101009290920a6001600160601b0381810219909316918316021790915560025460405163a9059cbb60e01b81526001600160a01b03868116600483015292851660248201529116915063a9059cbb90604401602060405180830381600087803b158015611d8d57600080fd5b505af1158015611da1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc591906155a7565b611de257604051631e9acf1760e31b815260040160405180910390fd5b5050565b611dee613703565b604080518082018252600091611e1d919084906002908390839080828437600092019190915250612e5d915050565b6000818152600e60205260409020549091506001600160a01b031615611e5957604051634a0b8fa760e01b815260048101829052602401610c03565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b89101610d96565b6001546001600160a01b03163314611f3f5760405162461bcd60e51b815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610c03565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600d54600090600160301b900460ff1615611fc45760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b0316611fff57604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680612050576040516379bfd40160e01b815260208401356004820152336024820152604401610c03565b600d5461ffff166120676060850160408601615758565b61ffff16108061208a575060c86120846060850160408601615758565b61ffff16115b156120d05761209f6060840160408501615758565b600d5460405163539c34bb60e11b815261ffff92831660048201529116602482015260c86044820152606401610c03565b600d5462010000900463ffffffff166120ef6080850160608601615858565b63ffffffff16111561213f5761210b6080840160608501615858565b600d54604051637aebf00f60e11b815263ffffffff9283166004820152620100009091049091166024820152604401610c03565b6101f461215260a0850160808601615858565b63ffffffff1611156121985761216e60a0840160808501615858565b6040516311ce1afb60e21b815263ffffffff90911660048201526101f46024820152604401610c03565b60006121a5826001615d9b565b604080518635602080830182905233838501528089013560608401526001600160401b0385166080808501919091528451808503909101815260a0808501865281519183019190912060c085019390935260e0808501849052855180860390910181526101009094019094528251920191909120929350906000906122359061223090890189615c9f565b613eff565b9050600061224282613f7c565b90508361224d613fed565b60208a013561226260808c0160608d01615858565b61227260a08d0160808e01615858565b338660405160200161228a9796959493929190615bad565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d60400160208101906123019190615758565b8e60600160208101906123149190615858565b8f60800160208101906123279190615858565b8960405161233a96959493929190615b6e565b60405180910390a450503360009081526004602090815260408083208983013584529091529020805467ffffffffffffffff19166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff16156123b95760405163769dd35360e11b815260040160405180910390fd5b6000336123c7600143615e1b565b600754604051606093841b6bffffffffffffffffffffffff199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b0390911690600061244683615ea5565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b0381111561248557612485615f38565b6040519080825280602002602001820160405280156124ae578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b03928316178355925160018301805490941691161790915592518051949550909361258f9260028501920190615145565b5061259f91506008905083614086565b5060405133815282907f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d9060200160405180910390a250905090565b600d54600160301b900460ff16156126065760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b03163314612631576040516344b0e3c360e01b815260040160405180910390fd5b6020811461265257604051638129bbcd60e01b815260040160405180910390fd5b6000612660828401846155c4565b6000818152600560205260409020549091506001600160a01b031661269857604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b0316918691906126bf8385615dc6565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166127079190615dc6565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a82878461275a9190615d83565b604080519283526020830191909152015b60405180910390a2505050505050565b612783613703565b600a544790600160601b90046001600160601b0316818111156127c3576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611afb5760006127d78284615e1b565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114612826576040519150601f19603f3d011682016040523d82523d6000602084013e61282b565b606091505b505090508061284d57604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b0387168152602081018490527f879c9ea2b9d5345b84ccd12610b032602808517cebdb795007f3dcb4df377317910160405180910390a15050505050565b61289e613703565b6000818152600560205260409020546001600160a01b03166128d357604051630fb532db60e11b815260040160405180910390fd5b600081815260056020526040902054610c0c9082906001600160a01b031661375f565b606060006129046008614092565b905080841061292657604051631390f2a160e01b815260040160405180910390fd5b60006129328486615d83565b905081811180612940575083155b61294a578061294c565b815b9050600061295a8683615e1b565b6001600160401b0381111561297157612971615f38565b60405190808252806020026020018201604052801561299a578160200160208202803683370190505b50905060005b81518110156129ed576129be6129b68883615d83565b60089061409c565b8282815181106129d0576129d0615f22565b6020908102919091010152806129e581615e8a565b9150506129a0565b5095945050505050565b6129ff613703565b60c861ffff87161115612a395760405163539c34bb60e11b815261ffff871660048201819052602482015260c86044820152606401610c03565b60008213612a5d576040516321ea67b360e11b815260048101839052602401610c03565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff19168817620100008702176effffffffffffffffff000000000000191667010000000000000085026effffffff0000000000000000000000191617600160581b83021790558a51601280548d87015192891667ffffffffffffffff199091161764010000000092891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff1615612bb65760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b0316612beb57604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612c44576000818152600560205260409081902060010154905163d084e97560e01b81526001600160a01b039091166004820152602401610c03565b6000818152600560209081526040918290208054336001600160a01b0319808316821784556001909301805490931690925583516001600160a01b0390911680825292810191909152909183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691015b60405180910390a25050565b60008281526005602052604090205482906001600160a01b031680612cf957604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612d2d57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612d585760405163769dd35360e11b815260040160405180910390fd5b60008481526005602052604090206002015460641415612d8b576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b031615612dc257610e6b565b6001600160a01b03831660008181526004602090815260408083208884528252808320805467ffffffffffffffff19166001908117909155600583528184206002018054918201815584529282902090920180546001600160a01b03191684179055905191825285917f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e191015b60405180910390a250505050565b600081604051602001612e709190615a39565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b031680612ec557604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612ef957604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff1615612f245760405163769dd35360e11b815260040160405180910390fd5b612f2d84611782565b15612f4b57604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316612fa7576040516379bfd40160e01b8152600481018590526001600160a01b0384166024820152604401610c03565b60008481526005602090815260408083206002018054825181850281018501909352808352919290919083018282801561300a57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612fec575b505050505090506000600182516130219190615e1b565b905060005b825181101561312d57856001600160a01b031683828151811061304b5761304b615f22565b60200260200101516001600160a01b0316141561311b57600083838151811061307657613076615f22565b6020026020010151905080600560008a815260200190815260200160002060020183815481106130a8576130a8615f22565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558981526005909152604090206002018054806130f3576130f3615f0c565b600082815260209020810160001990810180546001600160a01b03191690550190555061312d565b8061312581615e8a565b915050613026565b506001600160a01b03851660008181526004602090815260408083208a8452825291829020805467ffffffffffffffff19169055905191825287917f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7910161276b565b600f81815481106131a057600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b0316806131e957604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461321d57604051636c51fda960e11b81526001600160a01b0382166004820152602401610c03565b600d54600160301b900460ff16156132485760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b03848116911614610e6b5760008481526005602090815260409182902060010180546001600160a01b0319166001600160a01b03871690811790915582513381529182015285917f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19101612e4f565b6000818152600560205260408120548190819081906060906001600160a01b031661330e57604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b03909416939183918301828280156133b157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613393575b505050505090509450945094509450945091939590929450565b6133d3613703565b6002546001600160a01b03166133fc5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561344057600080fd5b505afa158015613454573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061347891906155dd565b600a549091506001600160601b0316818111156134b2576040516354ced18160e11b81526004810182905260248101839052604401610c03565b81811015611afb5760006134c68284615e1b565b60025460405163a9059cbb60e01b81526001600160a01b0387811660048301526024820184905292935091169063a9059cbb90604401602060405180830381600087803b15801561351657600080fd5b505af115801561352a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061354e91906155a7565b61356b57604051631f01ff1360e21b815260040160405180910390fd5b604080516001600160a01b0386168152602081018390527f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600910160405180910390a150505050565b600d54600160301b900460ff16156135de5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b031661361357604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c6136428385615dc6565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b031661368a9190615dc6565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f3f1ddc3ab1bdb39001ad76ca51a0e6f57ce6627c69f251d1de41622847721cde8234846136dd9190615d83565b60408051928352602083019190915201612cb5565b6136fa613703565b610c0c816140a8565b6000546001600160a01b0316331461375d5760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610c03565b565b60008061376b84613cb0565b60025491935091506001600160a01b03161580159061379257506001600160601b03821615155b156138425760025460405163a9059cbb60e01b81526001600160a01b0385811660048301526001600160601b03851660248301529091169063a9059cbb90604401602060405180830381600087803b1580156137ed57600080fd5b505af1158015613801573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061382591906155a7565b61384257604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613898576040519150601f19603f3d011682016040523d82523d6000602084013e61389d565b606091505b50509050806138bf57604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b604080516060810182526000808252602082018190529181019190915260006139478460000151612e5d565b6000818152600e60205260409020549091506001600160a01b03168061398357604051631dfd6e1360e21b815260048101839052602401610c03565b60008286608001516040516020016139a5929190918252602082015260400190565b60408051601f19818403018152918152815160209283012060008181526010909352912054909150806139eb57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d01519351613a1a978a979096959101615bf7565b604051602081830303815290604052805190602001208114613a4f5760405163354a450b60e21b815260040160405180910390fd5b6000613a5e8760000151614152565b905080613b36578651604051631d2827a760e31b81526001600160401b0390911660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e9413d389060240160206040518083038186803b158015613ad057600080fd5b505afa158015613ae4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b0891906155dd565b905080613b3657865160405163175dadad60e01b81526001600160401b039091166004820152602401610c03565b6000886080015182604051602001613b58929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c90506000613b7f8a83614249565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a611388811015613bba57600080fd5b611388810390508460408204820311613bd257600080fd5b50823b613bde57600080fd5b60008083516020850160008789f190505b9392505050565b60008115613c2457601254613c1d9086908690640100000000900463ffffffff16866142b4565b9050613c3e565b601254613c3b908690869063ffffffff168661431e565b90505b949350505050565b6000805b601354811015613ca757826001600160a01b031660138281548110613c7157613c71615f22565b6000918252602090912001546001600160a01b03161415613c955750600192915050565b80613c9f81615e8a565b915050613c4a565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287968796949594860193919290830182828015613d3c57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613d1e575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613e19576004600084604001518381518110613dc857613dc8615f22565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208982529092529020805467ffffffffffffffff1916905580613e1181615e8a565b915050613da1565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613e5160028301826151aa565b5050600085815260066020526040812055613e6d60088661440c565b50600a8054859190600090613e8c9084906001600160601b0316615e32565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613ed49190615e32565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081019091526000815281613f285750604080516020810190915260008152611355565b63125fa26760e31b613f3a8385615e5a565b6001600160e01b03191614613f6257604051632923fee760e11b815260040160405180910390fd5b613f6f8260048186615d59565b810190613bef91906155f6565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613fb591511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661a4b1811480614002575062066eed81145b1561407f5760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561404157600080fd5b505afa158015614055573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061407991906155dd565b91505090565b4391505090565b6000613bef8383614418565b6000611355825490565b6000613bef8383614467565b6001600160a01b0381163314156141015760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610c03565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b1811480614167575062066eed81145b80614174575062066eee81145b1561423a57610100836001600160401b031661418e613fed565b6141989190615e1b565b11806141b457506141a7613fed565b836001600160401b031610155b156141c25750600092915050565b6040516315a03d4160e11b81526001600160401b0384166004820152606490632b407a829060240160206040518083038186803b15801561420257600080fd5b505afa158015614216573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bef91906155dd565b50506001600160401b03164090565b600061427d8360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151614491565b60038360200151604051602001614295929190615b41565b60408051601f1981840301815291905280516020909101209392505050565b6000806142bf6146bc565b905060005a6142ce8888615d83565b6142d89190615e1b565b6142e29085615dfc565b905060006142fb63ffffffff871664e8d4a51000615dfc565b9050826143088284615d83565b6143129190615d83565b98975050505050505050565b600080614329614718565b90506000811361434f576040516321ea67b360e11b815260048101829052602401610c03565b60006143596146bc565b9050600082825a61436a8b8b615d83565b6143749190615e1b565b61437e9088615dfc565b6143889190615d83565b61439a90670de0b6b3a7640000615dfc565b6143a49190615de8565b905060006143bd63ffffffff881664e8d4a51000615dfc565b90506143d5816b033b2e3c9fd0803ce8000000615e1b565b8211156143f55760405163e80fa38160e01b815260040160405180910390fd5b6143ff8183615d83565b9998505050505050505050565b6000613bef83836147e7565b600081815260018301602052604081205461445f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611355565b506000611355565b600082600001828154811061447e5761447e615f22565b9060005260206000200154905092915050565b61449a896148da565b6144e65760405162461bcd60e51b815260206004820152601a60248201527f7075626c6963206b6579206973206e6f74206f6e2063757276650000000000006044820152606401610c03565b6144ef886148da565b61453b5760405162461bcd60e51b815260206004820152601560248201527f67616d6d61206973206e6f74206f6e20637572766500000000000000000000006044820152606401610c03565b614544836148da565b6145905760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610c03565b614599826148da565b6145e55760405162461bcd60e51b815260206004820152601c60248201527f73486173685769746e657373206973206e6f74206f6e206375727665000000006044820152606401610c03565b6145f1878a88876149b3565b61463d5760405162461bcd60e51b815260206004820152601960248201527f6164647228632a706b2b732a6729213d5f755769746e657373000000000000006044820152606401610c03565b60006146498a87614ad6565b9050600061465c898b878b868989614b3a565b9050600061466d838d8d8a86614c5a565b9050808a146146ae5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610c03565b505050505050505050505050565b60004661a4b18114806146d1575062066eed81145b1561471057606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561404157600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093670100000000000000900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561477a57600080fd5b505afa15801561478e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906147b29190615873565b5094509092508491505080156147d657506147cd8242615e1b565b8463ffffffff16105b15613c3e5750601154949350505050565b600081815260018301602052604081205480156148d057600061480b600183615e1b565b855490915060009061481f90600190615e1b565b905081811461488457600086600001828154811061483f5761483f615f22565b906000526020600020015490508087600001848154811061486257614862615f22565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061489557614895615f0c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611355565b6000915050611355565b80516000906401000003d019116149335760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420782d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d0191161498c5760405162461bcd60e51b815260206004820152601260248201527f696e76616c696420792d6f7264696e61746500000000000000000000000000006044820152606401610c03565b60208201516401000003d0199080096149ac8360005b6020020151614c9a565b1492915050565b60006001600160a01b0382166149f95760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610c03565b602084015160009060011615614a1057601c614a13565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020820180845287905260ff88169282019290925260608101929092526080820183905291925060019060a0016020604051602081039080840390855afa158015614aae573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614ade6151c8565b614b0b60018484604051602001614af793929190615a18565b604051602081830303815290604052614cbe565b90505b614b17816148da565b611355578051604080516020810192909252614b339101614af7565b9050614b0e565b614b426151c8565b825186516401000003d0199081900691061415614ba15760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610c03565b614bac878988614d0c565b614bf85760405162461bcd60e51b815260206004820152601660248201527f4669727374206d756c20636865636b206661696c6564000000000000000000006044820152606401610c03565b614c03848685614d0c565b614c4f5760405162461bcd60e51b815260206004820152601760248201527f5365636f6e64206d756c20636865636b206661696c65640000000000000000006044820152606401610c03565b614312868484614e34565b600060028686868587604051602001614c78969594939291906159b9565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614cc66151c8565b614ccf82614efb565b8152614ce4614cdf8260006149a2565b614f36565b602082018190526002900660011415612386576020810180516401000003d019039052919050565b600082614d495760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610c03565b83516020850151600090614d5f90600290615ecc565b15614d6b57601c614d6e565b601b5b9050600070014551231950b75fc4402da1732fc9bebe198387096040805160008082526020820180845281905260ff86169282019290925260608101869052608081018390529192509060019060a0016020604051602081039080840390855afa158015614de0573d6000803e3d6000fd5b505050602060405103519050600086604051602001614dff91906159a7565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614e3c6151c8565b835160208086015185519186015160009384938493614e5d93909190614f56565b919450925090506401000003d019858209600114614ebd5760405162461bcd60e51b815260206004820152601960248201527f696e765a206d75737420626520696e7665727365206f66207a000000000000006044820152606401610c03565b60405180604001604052806401000003d01980614edc57614edc615ef6565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d019811061238657604080516020808201939093528151808203840181529082019091528051910120614f03565b6000611355826002614f4f6401000003d0196001615d83565b901c615036565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614f96838385856150d8565b9098509050614fa788828e886150fc565b9098509050614fb888828c876150fc565b90985090506000614fcb8d878b856150fc565b9098509050614fdc888286866150d8565b9098509050614fed88828e896150fc565b9098509050818114615022576401000003d019818a0998506401000003d01982890997506401000003d0198183099650615026565b8196505b5050505050509450945094915050565b6000806150416151e6565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152615073615204565b60208160c0846005600019fa9250826150ce5760405162461bcd60e51b815260206004820152601260248201527f6269674d6f64457870206661696c7572652100000000000000000000000000006044820152606401610c03565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b82805482825590600052602060002090810192821561519a579160200282015b8281111561519a57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190615165565b506151a6929150615222565b5090565b5080546000825590600052602060002090810190610c0c9190615222565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b808211156151a65760008155600101615223565b803561238681615f4e565b806040810183101561135557600080fd5b600082601f83011261526457600080fd5b61526c615cec565b80838560408601111561527e57600080fd5b60005b60028110156152a0578135845260209384019390910190600101615281565b509095945050505050565b600082601f8301126152bc57600080fd5b81356001600160401b03808211156152d6576152d6615f38565b604051601f8301601f19908116603f011681019082821181831017156152fe576152fe615f38565b8160405283815286602085880101111561531757600080fd5b836020870160208301376000602085830101528094505050505092915050565b600060c0828403121561534957600080fd5b615351615d14565b905081356001600160401b03808216821461536b57600080fd5b81835260208401356020840152615384604085016153ea565b6040840152615395606085016153ea565b60608401526153a660808501615237565b608084015260a08401359150808211156153bf57600080fd5b506153cc848285016152ab565b60a08301525092915050565b803561ffff8116811461238657600080fd5b803563ffffffff8116811461238657600080fd5b805169ffffffffffffffffffff8116811461238657600080fd5b80356001600160601b038116811461238657600080fd5b60006020828403121561544157600080fd5b8135613bef81615f4e565b6000806040838503121561545f57600080fd5b823561546a81615f4e565b915061547860208401615418565b90509250929050565b6000806040838503121561549457600080fd5b823561549f81615f4e565b915060208301356154af81615f4e565b809150509250929050565b600080606083850312156154cd57600080fd5b82356154d881615f4e565b91506154788460208501615242565b600080600080606085870312156154fd57600080fd5b843561550881615f4e565b93506020850135925060408501356001600160401b038082111561552b57600080fd5b818701915087601f83011261553f57600080fd5b81358181111561554e57600080fd5b88602082850101111561556057600080fd5b95989497505060200194505050565b60006040828403121561558157600080fd5b613bef8383615242565b60006040828403121561559d57600080fd5b613bef8383615253565b6000602082840312156155b957600080fd5b8151613bef81615f63565b6000602082840312156155d657600080fd5b5035919050565b6000602082840312156155ef57600080fd5b5051919050565b60006020828403121561560857600080fd5b604051602081018181106001600160401b038211171561562a5761562a615f38565b604052823561563881615f63565b81529392505050565b6000808284036101c081121561565657600080fd5b6101a08082121561566657600080fd5b61566e615d36565b915061567a8686615253565b82526156898660408701615253565b60208301526080850135604083015260a0850135606083015260c085013560808301526156b860e08601615237565b60a08301526101006156cc87828801615253565b60c08401526156df876101408801615253565b60e0840152610180860135908301529092508301356001600160401b0381111561570857600080fd5b61571485828601615337565b9150509250929050565b60006020828403121561573057600080fd5b81356001600160401b0381111561574657600080fd5b820160c08185031215613bef57600080fd5b60006020828403121561576a57600080fd5b613bef826153d8565b60008060008060008086880360e081121561578d57600080fd5b615796886153d8565b96506157a4602089016153ea565b95506157b2604089016153ea565b94506157c0606089016153ea565b9350608088013592506040609f19820112156157db57600080fd5b506157e4615cec565b6157f060a089016153ea565b81526157fe60c089016153ea565b6020820152809150509295509295509295565b6000806040838503121561582457600080fd5b8235915060208301356154af81615f4e565b6000806040838503121561584957600080fd5b50508035926020909101359150565b60006020828403121561586a57600080fd5b613bef826153ea565b600080600080600060a0868803121561588b57600080fd5b615894866153fe565b94506020860151935060408601519250606086015191506158b7608087016153fe565b90509295509295909350565b600081518084526020808501945080840160005b838110156158fc5781516001600160a01b0316875295820195908201906001016158d7565b509495945050505050565b8060005b6002811015610e6b57815184526020938401939091019060010161590b565b600081518084526020808501945080840160005b838110156158fc5781518752958201959082019060010161593e565b6000815180845260005b8181101561598057602081850181015186830182015201615964565b81811115615992576000602083870101525b50601f01601f19169290920160200192915050565b6159b18183615907565b604001919050565b8681526159c96020820187615907565b6159d66060820186615907565b6159e360a0820185615907565b6159f060e0820184615907565b60609190911b6bffffffffffffffffffffffff19166101208201526101340195945050505050565b838152615a286020820184615907565b606081019190915260800192915050565b604081016113558284615907565b602081526000613bef602083018461592a565b602081526000613bef602083018461595a565b6020815260ff8251166020820152602082015160408201526001600160a01b0360408301511660608201526000606083015160c06080840152615ab360e08401826158c3565b905060808401516001600160601b0380821660a08601528060a08701511660c086015250508091505092915050565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615b3357845183529383019391830191600101615b17565b509098975050505050505050565b82815260608101613bef6020830184615907565b828152604060208201526000613c3e604083018461592a565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261431260c083018461595a565b878152866020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143ff60e083018461595a565b8781526001600160401b0387166020820152856040820152600063ffffffff80871660608401528086166080840152506001600160a01b03841660a083015260e060c08301526143ff60e083018461595a565b60006001600160601b0380881683528087166020840152506001600160401b03851660408301526001600160a01b038416606083015260a06080830152615c9460a08301846158c3565b979650505050505050565b6000808335601e19843603018112615cb657600080fd5b8301803591506001600160401b03821115615cd057600080fd5b602001915036819003821315615ce557600080fd5b9250929050565b604080519081016001600160401b0381118282101715615d0e57615d0e615f38565b60405290565b60405160c081016001600160401b0381118282101715615d0e57615d0e615f38565b60405161012081016001600160401b0381118282101715615d0e57615d0e615f38565b60008085851115615d6957600080fd5b83861115615d7657600080fd5b5050820193919092039150565b60008219821115615d9657615d96615ee0565b500190565b60006001600160401b03808316818516808303821115615dbd57615dbd615ee0565b01949350505050565b60006001600160601b03808316818516808303821115615dbd57615dbd615ee0565b600082615df757615df7615ef6565b500490565b6000816000190483118215151615615e1657615e16615ee0565b500290565b600082821015615e2d57615e2d615ee0565b500390565b60006001600160601b0383811690831681811015615e5257615e52615ee0565b039392505050565b6001600160e01b03198135818116916004851015615e825780818660040360031b1b83161692505b505092915050565b6000600019821415615e9e57615e9e615ee0565b5060010190565b60006001600160401b0380831681811415615ec257615ec2615ee0565b6001019392505050565b600082615edb57615edb615ef6565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610c0c57600080fd5b8015158114610c0c57600080fdfea164736f6c6343000806000a", -} - -var VRFCoordinatorV2PlusABI = VRFCoordinatorV2PlusMetaData.ABI - -var VRFCoordinatorV2PlusBin = VRFCoordinatorV2PlusMetaData.Bin - -func DeployVRFCoordinatorV2Plus(auth *bind.TransactOpts, backend bind.ContractBackend, blockhashStore common.Address) (common.Address, *types.Transaction, *VRFCoordinatorV2Plus, error) { - parsed, err := VRFCoordinatorV2PlusMetaData.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(VRFCoordinatorV2PlusBin), backend, blockhashStore) - if err != nil { - return common.Address{}, nil, nil, err - } - return address, tx, &VRFCoordinatorV2Plus{VRFCoordinatorV2PlusCaller: VRFCoordinatorV2PlusCaller{contract: contract}, VRFCoordinatorV2PlusTransactor: VRFCoordinatorV2PlusTransactor{contract: contract}, VRFCoordinatorV2PlusFilterer: VRFCoordinatorV2PlusFilterer{contract: contract}}, nil -} - -type VRFCoordinatorV2Plus struct { - address common.Address - abi abi.ABI - VRFCoordinatorV2PlusCaller - VRFCoordinatorV2PlusTransactor - VRFCoordinatorV2PlusFilterer -} - -type VRFCoordinatorV2PlusCaller struct { - contract *bind.BoundContract -} - -type VRFCoordinatorV2PlusTransactor struct { - contract *bind.BoundContract -} - -type VRFCoordinatorV2PlusFilterer struct { - contract *bind.BoundContract -} - -type VRFCoordinatorV2PlusSession struct { - Contract *VRFCoordinatorV2Plus - CallOpts bind.CallOpts - TransactOpts bind.TransactOpts -} - -type VRFCoordinatorV2PlusCallerSession struct { - Contract *VRFCoordinatorV2PlusCaller - CallOpts bind.CallOpts -} - -type VRFCoordinatorV2PlusTransactorSession struct { - Contract *VRFCoordinatorV2PlusTransactor - TransactOpts bind.TransactOpts -} - -type VRFCoordinatorV2PlusRaw struct { - Contract *VRFCoordinatorV2Plus -} - -type VRFCoordinatorV2PlusCallerRaw struct { - Contract *VRFCoordinatorV2PlusCaller -} - -type VRFCoordinatorV2PlusTransactorRaw struct { - Contract *VRFCoordinatorV2PlusTransactor -} - -func NewVRFCoordinatorV2Plus(address common.Address, backend bind.ContractBackend) (*VRFCoordinatorV2Plus, error) { - abi, err := abi.JSON(strings.NewReader(VRFCoordinatorV2PlusABI)) - if err != nil { - return nil, err - } - contract, err := bindVRFCoordinatorV2Plus(address, backend, backend, backend) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2Plus{address: address, abi: abi, VRFCoordinatorV2PlusCaller: VRFCoordinatorV2PlusCaller{contract: contract}, VRFCoordinatorV2PlusTransactor: VRFCoordinatorV2PlusTransactor{contract: contract}, VRFCoordinatorV2PlusFilterer: VRFCoordinatorV2PlusFilterer{contract: contract}}, nil -} - -func NewVRFCoordinatorV2PlusCaller(address common.Address, caller bind.ContractCaller) (*VRFCoordinatorV2PlusCaller, error) { - contract, err := bindVRFCoordinatorV2Plus(address, caller, nil, nil) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusCaller{contract: contract}, nil -} - -func NewVRFCoordinatorV2PlusTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFCoordinatorV2PlusTransactor, error) { - contract, err := bindVRFCoordinatorV2Plus(address, nil, transactor, nil) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusTransactor{contract: contract}, nil -} - -func NewVRFCoordinatorV2PlusFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFCoordinatorV2PlusFilterer, error) { - contract, err := bindVRFCoordinatorV2Plus(address, nil, nil, filterer) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusFilterer{contract: contract}, nil -} - -func bindVRFCoordinatorV2Plus(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { - parsed, err := VRFCoordinatorV2PlusMetaData.GetAbi() - if err != nil { - return nil, err - } - return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _VRFCoordinatorV2Plus.Contract.VRFCoordinatorV2PlusCaller.contract.Call(opts, result, method, params...) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.VRFCoordinatorV2PlusTransactor.contract.Transfer(opts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.VRFCoordinatorV2PlusTransactor.contract.Transact(opts, method, params...) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { - return _VRFCoordinatorV2Plus.Contract.contract.Call(opts, result, method, params...) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.contract.Transfer(opts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.contract.Transact(opts, method, params...) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) BLOCKHASHSTORE(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "BLOCKHASH_STORE") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) BLOCKHASHSTORE() (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.BLOCKHASHSTORE(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) BLOCKHASHSTORE() (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.BLOCKHASHSTORE(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) LINK(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) LINK() (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.LINK(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) LINK() (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.LINK(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) LINKETHFEED(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "LINK_ETH_FEED") - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) LINKETHFEED() (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.LINKETHFEED(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) LINKETHFEED() (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.LINKETHFEED(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) MAXCONSUMERS() (uint16, error) { - return _VRFCoordinatorV2Plus.Contract.MAXCONSUMERS(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) MAXCONSUMERS() (uint16, error) { - return _VRFCoordinatorV2Plus.Contract.MAXCONSUMERS(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) MAXNUMWORDS(opts *bind.CallOpts) (uint32, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "MAX_NUM_WORDS") - - if err != nil { - return *new(uint32), err - } - - out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) MAXNUMWORDS() (uint32, error) { - return _VRFCoordinatorV2Plus.Contract.MAXNUMWORDS(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) MAXNUMWORDS() (uint32, error) { - return _VRFCoordinatorV2Plus.Contract.MAXNUMWORDS(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) MAXREQUESTCONFIRMATIONS(opts *bind.CallOpts) (uint16, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "MAX_REQUEST_CONFIRMATIONS") - - if err != nil { - return *new(uint16), err - } - - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) MAXREQUESTCONFIRMATIONS() (uint16, error) { - return _VRFCoordinatorV2Plus.Contract.MAXREQUESTCONFIRMATIONS(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) MAXREQUESTCONFIRMATIONS() (uint16, error) { - 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") - - if err != nil { - return *new(uint16), *new(uint32), *new([][32]byte), err - } - - out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) - out1 := *abi.ConvertType(out[1], new(uint32)).(*uint32) - out2 := *abi.ConvertType(out[2], new([][32]byte)).(*[][32]byte) - - return out0, out1, out2, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) GetRequestConfig() (uint16, uint32, [][32]byte, error) { - return _VRFCoordinatorV2Plus.Contract.GetRequestConfig(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) GetRequestConfig() (uint16, uint32, [][32]byte, error) { - return _VRFCoordinatorV2Plus.Contract.GetRequestConfig(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, - - error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "getSubscription", subId) - - outstruct := new(GetSubscription) - if err != nil { - return *outstruct, err - } - - outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.EthBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) - 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 - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) GetSubscription(subId *big.Int) (GetSubscription, - - error) { - return _VRFCoordinatorV2Plus.Contract.GetSubscription(&_VRFCoordinatorV2Plus.CallOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) GetSubscription(subId *big.Int) (GetSubscription, - - error) { - return _VRFCoordinatorV2Plus.Contract.GetSubscription(&_VRFCoordinatorV2Plus.CallOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) HashOfKey(opts *bind.CallOpts, publicKey [2]*big.Int) ([32]byte, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "hashOfKey", publicKey) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) { - return _VRFCoordinatorV2Plus.Contract.HashOfKey(&_VRFCoordinatorV2Plus.CallOpts, publicKey) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) HashOfKey(publicKey [2]*big.Int) ([32]byte, error) { - return _VRFCoordinatorV2Plus.Contract.HashOfKey(&_VRFCoordinatorV2Plus.CallOpts, publicKey) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) MigrationVersion(opts *bind.CallOpts) (uint8, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "migrationVersion") - - if err != nil { - return *new(uint8), err - } - - out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) MigrationVersion() (uint8, error) { - return _VRFCoordinatorV2Plus.Contract.MigrationVersion(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) MigrationVersion() (uint8, error) { - return _VRFCoordinatorV2Plus.Contract.MigrationVersion(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) Owner(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) Owner() (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.Owner(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) Owner() (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.Owner(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "pendingRequestExists", subId) - - if err != nil { - return *new(bool), err - } - - out0 := *abi.ConvertType(out[0], new(bool)).(*bool) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) PendingRequestExists(subId *big.Int) (bool, error) { - return _VRFCoordinatorV2Plus.Contract.PendingRequestExists(&_VRFCoordinatorV2Plus.CallOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) PendingRequestExists(subId *big.Int) (bool, error) { - return _VRFCoordinatorV2Plus.Contract.PendingRequestExists(&_VRFCoordinatorV2Plus.CallOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) SConfig(opts *bind.CallOpts) (SConfig, - - error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "s_config") - - outstruct := new(SConfig) - if err != nil { - return *outstruct, err - } - - outstruct.MinimumRequestConfirmations = *abi.ConvertType(out[0], new(uint16)).(*uint16) - outstruct.MaxGasLimit = *abi.ConvertType(out[1], 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 - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SConfig() (SConfig, - - error) { - return _VRFCoordinatorV2Plus.Contract.SConfig(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) SConfig() (SConfig, - - error) { - return _VRFCoordinatorV2Plus.Contract.SConfig(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "s_currentSubNonce") - - if err != nil { - return *new(uint64), err - } - - out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SCurrentSubNonce() (uint64, error) { - return _VRFCoordinatorV2Plus.Contract.SCurrentSubNonce(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) SCurrentSubNonce() (uint64, error) { - return _VRFCoordinatorV2Plus.Contract.SCurrentSubNonce(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "s_fallbackWeiPerUnitLink") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SFallbackWeiPerUnitLink() (*big.Int, error) { - return _VRFCoordinatorV2Plus.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) SFallbackWeiPerUnitLink() (*big.Int, error) { - return _VRFCoordinatorV2Plus.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) SFeeConfig(opts *bind.CallOpts) (SFeeConfig, - - error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "s_feeConfig") - - outstruct := new(SFeeConfig) - if err != nil { - return *outstruct, err - } - - outstruct.FulfillmentFlatFeeLinkPPM = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.FulfillmentFlatFeeEthPPM = *abi.ConvertType(out[1], new(uint32)).(*uint32) - - return *outstruct, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SFeeConfig() (SFeeConfig, - - error) { - return _VRFCoordinatorV2Plus.Contract.SFeeConfig(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) SFeeConfig() (SFeeConfig, - - error) { - return _VRFCoordinatorV2Plus.Contract.SFeeConfig(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "s_provingKeyHashes", arg0) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) { - return _VRFCoordinatorV2Plus.Contract.SProvingKeyHashes(&_VRFCoordinatorV2Plus.CallOpts, arg0) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) SProvingKeyHashes(arg0 *big.Int) ([32]byte, error) { - return _VRFCoordinatorV2Plus.Contract.SProvingKeyHashes(&_VRFCoordinatorV2Plus.CallOpts, arg0) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (common.Address, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "s_provingKeys", arg0) - - if err != nil { - return *new(common.Address), err - } - - out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SProvingKeys(arg0 [32]byte) (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.SProvingKeys(&_VRFCoordinatorV2Plus.CallOpts, arg0) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) SProvingKeys(arg0 [32]byte) (common.Address, error) { - return _VRFCoordinatorV2Plus.Contract.SProvingKeys(&_VRFCoordinatorV2Plus.CallOpts, arg0) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "s_requestCommitments", arg0) - - if err != nil { - return *new([32]byte), err - } - - out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SRequestCommitments(arg0 *big.Int) ([32]byte, error) { - return _VRFCoordinatorV2Plus.Contract.SRequestCommitments(&_VRFCoordinatorV2Plus.CallOpts, arg0) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) SRequestCommitments(arg0 *big.Int) ([32]byte, error) { - return _VRFCoordinatorV2Plus.Contract.SRequestCommitments(&_VRFCoordinatorV2Plus.CallOpts, arg0) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) STotalBalance(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "s_totalBalance") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) STotalBalance() (*big.Int, error) { - return _VRFCoordinatorV2Plus.Contract.STotalBalance(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) STotalBalance() (*big.Int, error) { - return _VRFCoordinatorV2Plus.Contract.STotalBalance(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCaller) STotalEthBalance(opts *bind.CallOpts) (*big.Int, error) { - var out []interface{} - err := _VRFCoordinatorV2Plus.contract.Call(opts, &out, "s_totalEthBalance") - - if err != nil { - return *new(*big.Int), err - } - - out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - - return out0, err - -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) STotalEthBalance() (*big.Int, error) { - return _VRFCoordinatorV2Plus.Contract.STotalEthBalance(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusCallerSession) STotalEthBalance() (*big.Int, error) { - return _VRFCoordinatorV2Plus.Contract.STotalEthBalance(&_VRFCoordinatorV2Plus.CallOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "acceptOwnership") -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) AcceptOwnership() (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.AcceptOwnership(&_VRFCoordinatorV2Plus.TransactOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) AcceptOwnership() (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.AcceptOwnership(&_VRFCoordinatorV2Plus.TransactOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorV2Plus.TransactOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.AcceptSubscriptionOwnerTransfer(&_VRFCoordinatorV2Plus.TransactOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "addConsumer", subId, consumer) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.AddConsumer(&_VRFCoordinatorV2Plus.TransactOpts, subId, consumer) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.AddConsumer(&_VRFCoordinatorV2Plus.TransactOpts, subId, consumer) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "cancelSubscription", subId, to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.CancelSubscription(&_VRFCoordinatorV2Plus.TransactOpts, subId, to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.CancelSubscription(&_VRFCoordinatorV2Plus.TransactOpts, subId, to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "createSubscription") -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) CreateSubscription() (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.CreateSubscription(&_VRFCoordinatorV2Plus.TransactOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) CreateSubscription() (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.CreateSubscription(&_VRFCoordinatorV2Plus.TransactOpts) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "deregisterMigratableCoordinator", target) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.DeregisterMigratableCoordinator(&_VRFCoordinatorV2Plus.TransactOpts, target) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) DeregisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.DeregisterMigratableCoordinator(&_VRFCoordinatorV2Plus.TransactOpts, target) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) DeregisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "deregisterProvingKey", publicProvingKey) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) DeregisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.DeregisterProvingKey(&_VRFCoordinatorV2Plus.TransactOpts, publicProvingKey) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) DeregisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.DeregisterProvingKey(&_VRFCoordinatorV2Plus.TransactOpts, publicProvingKey) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV2PlusRequestCommitment) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "fulfillRandomWords", proof, rc) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV2PlusRequestCommitment) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.FulfillRandomWords(&_VRFCoordinatorV2Plus.TransactOpts, proof, rc) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV2PlusRequestCommitment) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.FulfillRandomWords(&_VRFCoordinatorV2Plus.TransactOpts, proof, rc) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) FundSubscriptionWithEth(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "fundSubscriptionWithEth", subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) FundSubscriptionWithEth(subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.FundSubscriptionWithEth(&_VRFCoordinatorV2Plus.TransactOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) FundSubscriptionWithEth(subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.FundSubscriptionWithEth(&_VRFCoordinatorV2Plus.TransactOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "migrate", subId, newCoordinator) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.Migrate(&_VRFCoordinatorV2Plus.TransactOpts, subId, newCoordinator) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) Migrate(subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.Migrate(&_VRFCoordinatorV2Plus.TransactOpts, subId, newCoordinator) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) OnTokenTransfer(opts *bind.TransactOpts, arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "onTokenTransfer", arg0, amount, data) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.OnTokenTransfer(&_VRFCoordinatorV2Plus.TransactOpts, arg0, amount, data) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) OnTokenTransfer(arg0 common.Address, amount *big.Int, data []byte) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.OnTokenTransfer(&_VRFCoordinatorV2Plus.TransactOpts, arg0, amount, data) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "oracleWithdraw", recipient, amount) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.OracleWithdraw(&_VRFCoordinatorV2Plus.TransactOpts, recipient, amount) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) OracleWithdraw(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.OracleWithdraw(&_VRFCoordinatorV2Plus.TransactOpts, recipient, amount) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) OracleWithdrawEth(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "oracleWithdrawEth", recipient, amount) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) OracleWithdrawEth(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.OracleWithdrawEth(&_VRFCoordinatorV2Plus.TransactOpts, recipient, amount) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) OracleWithdrawEth(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.OracleWithdrawEth(&_VRFCoordinatorV2Plus.TransactOpts, recipient, amount) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "ownerCancelSubscription", subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.OwnerCancelSubscription(&_VRFCoordinatorV2Plus.TransactOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) OwnerCancelSubscription(subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.OwnerCancelSubscription(&_VRFCoordinatorV2Plus.TransactOpts, subId) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) RecoverEthFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "recoverEthFunds", to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) RecoverEthFunds(to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RecoverEthFunds(&_VRFCoordinatorV2Plus.TransactOpts, to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) RecoverEthFunds(to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RecoverEthFunds(&_VRFCoordinatorV2Plus.TransactOpts, to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "recoverFunds", to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) RecoverFunds(to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RecoverFunds(&_VRFCoordinatorV2Plus.TransactOpts, to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) RecoverFunds(to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RecoverFunds(&_VRFCoordinatorV2Plus.TransactOpts, to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "registerMigratableCoordinator", target) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorV2Plus.TransactOpts, target) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) RegisterMigratableCoordinator(target common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorV2Plus.TransactOpts, target) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) RegisterProvingKey(opts *bind.TransactOpts, oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "registerProvingKey", oracle, publicProvingKey) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) RegisterProvingKey(oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RegisterProvingKey(&_VRFCoordinatorV2Plus.TransactOpts, oracle, publicProvingKey) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) RegisterProvingKey(oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RegisterProvingKey(&_VRFCoordinatorV2Plus.TransactOpts, oracle, publicProvingKey) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "removeConsumer", subId, consumer) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RemoveConsumer(&_VRFCoordinatorV2Plus.TransactOpts, subId, consumer) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RemoveConsumer(&_VRFCoordinatorV2Plus.TransactOpts, subId, consumer) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "requestRandomWords", req) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RequestRandomWords(&_VRFCoordinatorV2Plus.TransactOpts, req) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RequestRandomWords(&_VRFCoordinatorV2Plus.TransactOpts, req) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subId, newOwner) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorV2Plus.TransactOpts, subId, newOwner) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.RequestSubscriptionOwnerTransfer(&_VRFCoordinatorV2Plus.TransactOpts, subId, newOwner) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactor) SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV2PlusFeeConfig) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "setConfig", minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV2PlusFeeConfig) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.SetConfig(&_VRFCoordinatorV2Plus.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV2PlusFeeConfig) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.SetConfig(&_VRFCoordinatorV2Plus.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig) -} - -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) SetLINKAndLINKETHFeed(link common.Address, linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.SetLINKAndLINKETHFeed(&_VRFCoordinatorV2Plus.TransactOpts, link, 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) { - return _VRFCoordinatorV2Plus.contract.Transact(opts, "transferOwnership", to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.TransferOwnership(&_VRFCoordinatorV2Plus.TransactOpts, to) -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2Plus.Contract.TransferOwnership(&_VRFCoordinatorV2Plus.TransactOpts, to) -} - -type VRFCoordinatorV2PlusConfigSetIterator struct { - Event *VRFCoordinatorV2PlusConfigSet - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusConfigSetIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusConfigSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusConfigSet) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusConfigSetIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusConfigSetIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusConfigSet struct { - MinimumRequestConfirmations uint16 - MaxGasLimit uint32 - StalenessSeconds uint32 - GasAfterPaymentCalculation uint32 - FallbackWeiPerUnitLink *big.Int - FeeConfig VRFCoordinatorV2PlusFeeConfig - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusConfigSetIterator, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "ConfigSet") - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusConfigSetIterator{contract: _VRFCoordinatorV2Plus.contract, event: "ConfigSet", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusConfigSet) (event.Subscription, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.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(VRFCoordinatorV2PlusConfigSet) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseConfigSet(log types.Log) (*VRFCoordinatorV2PlusConfigSet, error) { - event := new(VRFCoordinatorV2PlusConfigSet) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "ConfigSet", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusCoordinatorDeregisteredIterator struct { - Event *VRFCoordinatorV2PlusCoordinatorDeregistered - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusCoordinatorDeregisteredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusCoordinatorDeregistered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusCoordinatorDeregistered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusCoordinatorDeregisteredIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusCoordinatorDeregisteredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusCoordinatorDeregistered struct { - CoordinatorAddress common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusCoordinatorDeregisteredIterator, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "CoordinatorDeregistered") - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusCoordinatorDeregisteredIterator{contract: _VRFCoordinatorV2Plus.contract, event: "CoordinatorDeregistered", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusCoordinatorDeregistered) (event.Subscription, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "CoordinatorDeregistered") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusCoordinatorDeregistered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorV2PlusCoordinatorDeregistered, error) { - event := new(VRFCoordinatorV2PlusCoordinatorDeregistered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "CoordinatorDeregistered", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusCoordinatorRegisteredIterator struct { - Event *VRFCoordinatorV2PlusCoordinatorRegistered - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusCoordinatorRegisteredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusCoordinatorRegistered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusCoordinatorRegistered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusCoordinatorRegisteredIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusCoordinatorRegisteredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusCoordinatorRegistered struct { - CoordinatorAddress common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusCoordinatorRegisteredIterator, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "CoordinatorRegistered") - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusCoordinatorRegisteredIterator{contract: _VRFCoordinatorV2Plus.contract, event: "CoordinatorRegistered", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusCoordinatorRegistered) (event.Subscription, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "CoordinatorRegistered") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusCoordinatorRegistered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorV2PlusCoordinatorRegistered, error) { - event := new(VRFCoordinatorV2PlusCoordinatorRegistered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "CoordinatorRegistered", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusEthFundsRecoveredIterator struct { - Event *VRFCoordinatorV2PlusEthFundsRecovered - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusEthFundsRecoveredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusEthFundsRecovered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusEthFundsRecovered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusEthFundsRecoveredIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusEthFundsRecoveredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusEthFundsRecovered struct { - To common.Address - Amount *big.Int - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterEthFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusEthFundsRecoveredIterator, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "EthFundsRecovered") - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusEthFundsRecoveredIterator{contract: _VRFCoordinatorV2Plus.contract, event: "EthFundsRecovered", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchEthFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusEthFundsRecovered) (event.Subscription, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "EthFundsRecovered") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusEthFundsRecovered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "EthFundsRecovered", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseEthFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusEthFundsRecovered, error) { - event := new(VRFCoordinatorV2PlusEthFundsRecovered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "EthFundsRecovered", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusFundsRecoveredIterator struct { - Event *VRFCoordinatorV2PlusFundsRecovered - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusFundsRecoveredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusFundsRecovered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusFundsRecovered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusFundsRecoveredIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusFundsRecoveredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusFundsRecovered struct { - To common.Address - Amount *big.Int - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusFundsRecoveredIterator, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "FundsRecovered") - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusFundsRecoveredIterator{contract: _VRFCoordinatorV2Plus.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusFundsRecovered) (event.Subscription, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.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(VRFCoordinatorV2PlusFundsRecovered) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusFundsRecovered, error) { - event := new(VRFCoordinatorV2PlusFundsRecovered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "FundsRecovered", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusMigrationCompletedIterator struct { - Event *VRFCoordinatorV2PlusMigrationCompleted - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusMigrationCompletedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusMigrationCompleted) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusMigrationCompleted) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusMigrationCompletedIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusMigrationCompletedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusMigrationCompleted struct { - NewCoordinator common.Address - SubId *big.Int - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusMigrationCompletedIterator, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "MigrationCompleted") - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusMigrationCompletedIterator{contract: _VRFCoordinatorV2Plus.contract, event: "MigrationCompleted", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusMigrationCompleted) (event.Subscription, error) { - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "MigrationCompleted") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusMigrationCompleted) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseMigrationCompleted(log types.Log) (*VRFCoordinatorV2PlusMigrationCompleted, error) { - event := new(VRFCoordinatorV2PlusMigrationCompleted) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusOwnershipTransferRequestedIterator struct { - Event *VRFCoordinatorV2PlusOwnershipTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusOwnershipTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusOwnershipTransferRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusOwnershipTransferRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusOwnershipTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusOwnershipTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusOwnershipTransferRequested struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV2PlusOwnershipTransferRequestedIterator, 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 := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusOwnershipTransferRequestedIterator{contract: _VRFCoordinatorV2Plus.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusOwnershipTransferRequested, 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 := _VRFCoordinatorV2Plus.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(VRFCoordinatorV2PlusOwnershipTransferRequested) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorV2PlusOwnershipTransferRequested, error) { - event := new(VRFCoordinatorV2PlusOwnershipTransferRequested) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusOwnershipTransferredIterator struct { - Event *VRFCoordinatorV2PlusOwnershipTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusOwnershipTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusOwnershipTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusOwnershipTransferredIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusOwnershipTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusOwnershipTransferred struct { - From common.Address - To common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV2PlusOwnershipTransferredIterator, 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 := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusOwnershipTransferredIterator{contract: _VRFCoordinatorV2Plus.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusOwnershipTransferred, 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 := _VRFCoordinatorV2Plus.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(VRFCoordinatorV2PlusOwnershipTransferred) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorV2PlusOwnershipTransferred, error) { - event := new(VRFCoordinatorV2PlusOwnershipTransferred) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusProvingKeyDeregisteredIterator struct { - Event *VRFCoordinatorV2PlusProvingKeyDeregistered - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusProvingKeyDeregisteredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusProvingKeyDeregistered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusProvingKeyDeregistered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusProvingKeyDeregisteredIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusProvingKeyDeregisteredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusProvingKeyDeregistered struct { - KeyHash [32]byte - Oracle common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterProvingKeyDeregistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV2PlusProvingKeyDeregisteredIterator, error) { - - var oracleRule []interface{} - for _, oracleItem := range oracle { - oracleRule = append(oracleRule, oracleItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "ProvingKeyDeregistered", oracleRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusProvingKeyDeregisteredIterator{contract: _VRFCoordinatorV2Plus.contract, event: "ProvingKeyDeregistered", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchProvingKeyDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusProvingKeyDeregistered, oracle []common.Address) (event.Subscription, error) { - - var oracleRule []interface{} - for _, oracleItem := range oracle { - oracleRule = append(oracleRule, oracleItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "ProvingKeyDeregistered", oracleRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusProvingKeyDeregistered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "ProvingKeyDeregistered", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseProvingKeyDeregistered(log types.Log) (*VRFCoordinatorV2PlusProvingKeyDeregistered, error) { - event := new(VRFCoordinatorV2PlusProvingKeyDeregistered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "ProvingKeyDeregistered", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusProvingKeyRegisteredIterator struct { - Event *VRFCoordinatorV2PlusProvingKeyRegistered - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusProvingKeyRegisteredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusProvingKeyRegistered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusProvingKeyRegistered) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusProvingKeyRegisteredIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusProvingKeyRegisteredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusProvingKeyRegistered struct { - KeyHash [32]byte - Oracle common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterProvingKeyRegistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV2PlusProvingKeyRegisteredIterator, error) { - - var oracleRule []interface{} - for _, oracleItem := range oracle { - oracleRule = append(oracleRule, oracleItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "ProvingKeyRegistered", oracleRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusProvingKeyRegisteredIterator{contract: _VRFCoordinatorV2Plus.contract, event: "ProvingKeyRegistered", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusProvingKeyRegistered, oracle []common.Address) (event.Subscription, error) { - - var oracleRule []interface{} - for _, oracleItem := range oracle { - oracleRule = append(oracleRule, oracleItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "ProvingKeyRegistered", oracleRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusProvingKeyRegistered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "ProvingKeyRegistered", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorV2PlusProvingKeyRegistered, error) { - event := new(VRFCoordinatorV2PlusProvingKeyRegistered) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "ProvingKeyRegistered", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusRandomWordsFulfilledIterator struct { - Event *VRFCoordinatorV2PlusRandomWordsFulfilled - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusRandomWordsFulfilledIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusRandomWordsFulfilled) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusRandomWordsFulfilled) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusRandomWordsFulfilledIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusRandomWordsFulfilledIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusRandomWordsFulfilled struct { - RequestId *big.Int - OutputSeed *big.Int - SubID *big.Int - Payment *big.Int - Success bool - Raw types.Log -} - -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) - } - - 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, subID []*big.Int) (event.Subscription, error) { - - var requestIdRule []interface{} - for _, requestIdItem := range requestId { - requestIdRule = append(requestIdRule, requestIdItem) - } - - var subIDRule []interface{} - for _, subIDItem := range subID { - subIDRule = append(subIDRule, subIDItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIDRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusRandomWordsFulfilled) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorV2PlusRandomWordsFulfilled, error) { - event := new(VRFCoordinatorV2PlusRandomWordsFulfilled) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusRandomWordsRequestedIterator struct { - Event *VRFCoordinatorV2PlusRandomWordsRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusRandomWordsRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusRandomWordsRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusRandomWordsRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusRandomWordsRequestedIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusRandomWordsRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusRandomWordsRequested struct { - KeyHash [32]byte - RequestId *big.Int - PreSeed *big.Int - SubId *big.Int - MinimumRequestConfirmations uint16 - CallbackGasLimit uint32 - NumWords uint32 - ExtraArgs []byte - Sender common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorV2PlusRandomWordsRequestedIterator, error) { - - var keyHashRule []interface{} - for _, keyHashItem := range keyHash { - keyHashRule = append(keyHashRule, keyHashItem) - } - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - var senderRule []interface{} - for _, senderItem := range sender { - senderRule = append(senderRule, senderItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusRandomWordsRequestedIterator{contract: _VRFCoordinatorV2Plus.contract, event: "RandomWordsRequested", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusRandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) { - - var keyHashRule []interface{} - for _, keyHashItem := range keyHash { - keyHashRule = append(keyHashRule, keyHashItem) - } - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - var senderRule []interface{} - for _, senderItem := range sender { - senderRule = append(senderRule, senderItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusRandomWordsRequested) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorV2PlusRandomWordsRequested, error) { - event := new(VRFCoordinatorV2PlusRandomWordsRequested) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusSubscriptionCanceledIterator struct { - Event *VRFCoordinatorV2PlusSubscriptionCanceled - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusSubscriptionCanceledIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionCanceled) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionCanceled) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusSubscriptionCanceledIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusSubscriptionCanceledIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusSubscriptionCanceled struct { - SubId *big.Int - To common.Address - AmountLink *big.Int - AmountEth *big.Int - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionCanceledIterator, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "SubscriptionCanceled", subIdRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusSubscriptionCanceledIterator{contract: _VRFCoordinatorV2Plus.contract, event: "SubscriptionCanceled", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionCanceled, subId []*big.Int) (event.Subscription, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "SubscriptionCanceled", subIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusSubscriptionCanceled) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorV2PlusSubscriptionCanceled, error) { - event := new(VRFCoordinatorV2PlusSubscriptionCanceled) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "SubscriptionCanceled", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusSubscriptionConsumerAddedIterator struct { - Event *VRFCoordinatorV2PlusSubscriptionConsumerAdded - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusSubscriptionConsumerAddedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionConsumerAdded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionConsumerAdded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusSubscriptionConsumerAddedIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusSubscriptionConsumerAddedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusSubscriptionConsumerAdded struct { - SubId *big.Int - Consumer common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionConsumerAddedIterator, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "SubscriptionConsumerAdded", subIdRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusSubscriptionConsumerAddedIterator{contract: _VRFCoordinatorV2Plus.contract, event: "SubscriptionConsumerAdded", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "SubscriptionConsumerAdded", subIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusSubscriptionConsumerAdded) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorV2PlusSubscriptionConsumerAdded, error) { - event := new(VRFCoordinatorV2PlusSubscriptionConsumerAdded) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "SubscriptionConsumerAdded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusSubscriptionConsumerRemovedIterator struct { - Event *VRFCoordinatorV2PlusSubscriptionConsumerRemoved - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusSubscriptionConsumerRemovedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionConsumerRemoved) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionConsumerRemoved) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusSubscriptionConsumerRemovedIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusSubscriptionConsumerRemovedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusSubscriptionConsumerRemoved struct { - SubId *big.Int - Consumer common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionConsumerRemovedIterator, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "SubscriptionConsumerRemoved", subIdRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusSubscriptionConsumerRemovedIterator{contract: _VRFCoordinatorV2Plus.contract, event: "SubscriptionConsumerRemoved", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "SubscriptionConsumerRemoved", subIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusSubscriptionConsumerRemoved) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorV2PlusSubscriptionConsumerRemoved, error) { - event := new(VRFCoordinatorV2PlusSubscriptionConsumerRemoved) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "SubscriptionConsumerRemoved", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusSubscriptionCreatedIterator struct { - Event *VRFCoordinatorV2PlusSubscriptionCreated - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusSubscriptionCreatedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionCreated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionCreated) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusSubscriptionCreatedIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusSubscriptionCreatedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusSubscriptionCreated struct { - SubId *big.Int - Owner common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionCreatedIterator, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "SubscriptionCreated", subIdRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusSubscriptionCreatedIterator{contract: _VRFCoordinatorV2Plus.contract, event: "SubscriptionCreated", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionCreated, subId []*big.Int) (event.Subscription, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "SubscriptionCreated", subIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusSubscriptionCreated) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorV2PlusSubscriptionCreated, error) { - event := new(VRFCoordinatorV2PlusSubscriptionCreated) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "SubscriptionCreated", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusSubscriptionFundedIterator struct { - Event *VRFCoordinatorV2PlusSubscriptionFunded - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusSubscriptionFundedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionFunded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionFunded) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusSubscriptionFundedIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusSubscriptionFundedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusSubscriptionFunded struct { - SubId *big.Int - OldBalance *big.Int - NewBalance *big.Int - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionFundedIterator, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "SubscriptionFunded", subIdRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusSubscriptionFundedIterator{contract: _VRFCoordinatorV2Plus.contract, event: "SubscriptionFunded", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionFunded, subId []*big.Int) (event.Subscription, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "SubscriptionFunded", subIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusSubscriptionFunded) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorV2PlusSubscriptionFunded, error) { - event := new(VRFCoordinatorV2PlusSubscriptionFunded) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "SubscriptionFunded", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusSubscriptionFundedWithEthIterator struct { - Event *VRFCoordinatorV2PlusSubscriptionFundedWithEth - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusSubscriptionFundedWithEthIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionFundedWithEth) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionFundedWithEth) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusSubscriptionFundedWithEthIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusSubscriptionFundedWithEthIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusSubscriptionFundedWithEth struct { - SubId *big.Int - OldEthBalance *big.Int - NewEthBalance *big.Int - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterSubscriptionFundedWithEth(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionFundedWithEthIterator, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "SubscriptionFundedWithEth", subIdRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusSubscriptionFundedWithEthIterator{contract: _VRFCoordinatorV2Plus.contract, event: "SubscriptionFundedWithEth", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchSubscriptionFundedWithEth(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionFundedWithEth, subId []*big.Int) (event.Subscription, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "SubscriptionFundedWithEth", subIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusSubscriptionFundedWithEth) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "SubscriptionFundedWithEth", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseSubscriptionFundedWithEth(log types.Log) (*VRFCoordinatorV2PlusSubscriptionFundedWithEth, error) { - event := new(VRFCoordinatorV2PlusSubscriptionFundedWithEth) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "SubscriptionFundedWithEth", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusSubscriptionOwnerTransferRequestedIterator struct { - Event *VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusSubscriptionOwnerTransferRequestedIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusSubscriptionOwnerTransferRequestedIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusSubscriptionOwnerTransferRequestedIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested struct { - SubId *big.Int - From common.Address - To common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionOwnerTransferRequestedIterator, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusSubscriptionOwnerTransferRequestedIterator{contract: _VRFCoordinatorV2Plus.contract, event: "SubscriptionOwnerTransferRequested", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "SubscriptionOwnerTransferRequested", subIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested, error) { - event := new(VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "SubscriptionOwnerTransferRequested", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -type VRFCoordinatorV2PlusSubscriptionOwnerTransferredIterator struct { - Event *VRFCoordinatorV2PlusSubscriptionOwnerTransferred - - contract *bind.BoundContract - event string - - logs chan types.Log - sub ethereum.Subscription - done bool - fail error -} - -func (it *VRFCoordinatorV2PlusSubscriptionOwnerTransferredIterator) Next() bool { - - if it.fail != nil { - return false - } - - if it.done { - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionOwnerTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - - select { - case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusSubscriptionOwnerTransferred) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -func (it *VRFCoordinatorV2PlusSubscriptionOwnerTransferredIterator) Error() error { - return it.fail -} - -func (it *VRFCoordinatorV2PlusSubscriptionOwnerTransferredIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -type VRFCoordinatorV2PlusSubscriptionOwnerTransferred struct { - SubId *big.Int - From common.Address - To common.Address - Raw types.Log -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionOwnerTransferredIterator, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.FilterLogs(opts, "SubscriptionOwnerTransferred", subIdRule) - if err != nil { - return nil, err - } - return &VRFCoordinatorV2PlusSubscriptionOwnerTransferredIterator{contract: _VRFCoordinatorV2Plus.contract, event: "SubscriptionOwnerTransferred", logs: logs, sub: sub}, nil -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) { - - var subIdRule []interface{} - for _, subIdItem := range subId { - subIdRule = append(subIdRule, subIdItem) - } - - logs, sub, err := _VRFCoordinatorV2Plus.contract.WatchLogs(opts, "SubscriptionOwnerTransferred", subIdRule) - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - - event := new(VRFCoordinatorV2PlusSubscriptionOwnerTransferred) - if err := _VRFCoordinatorV2Plus.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 (_VRFCoordinatorV2Plus *VRFCoordinatorV2PlusFilterer) ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorV2PlusSubscriptionOwnerTransferred, error) { - event := new(VRFCoordinatorV2PlusSubscriptionOwnerTransferred) - if err := _VRFCoordinatorV2Plus.contract.UnpackLog(event, "SubscriptionOwnerTransferred", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - -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 -} -type SFeeConfig struct { - FulfillmentFlatFeeLinkPPM uint32 - FulfillmentFlatFeeEthPPM uint32 -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2Plus) ParseLog(log types.Log) (generated.AbigenLog, error) { - switch log.Topics[0] { - case _VRFCoordinatorV2Plus.abi.Events["ConfigSet"].ID: - return _VRFCoordinatorV2Plus.ParseConfigSet(log) - case _VRFCoordinatorV2Plus.abi.Events["CoordinatorDeregistered"].ID: - return _VRFCoordinatorV2Plus.ParseCoordinatorDeregistered(log) - case _VRFCoordinatorV2Plus.abi.Events["CoordinatorRegistered"].ID: - return _VRFCoordinatorV2Plus.ParseCoordinatorRegistered(log) - case _VRFCoordinatorV2Plus.abi.Events["EthFundsRecovered"].ID: - return _VRFCoordinatorV2Plus.ParseEthFundsRecovered(log) - case _VRFCoordinatorV2Plus.abi.Events["FundsRecovered"].ID: - return _VRFCoordinatorV2Plus.ParseFundsRecovered(log) - case _VRFCoordinatorV2Plus.abi.Events["MigrationCompleted"].ID: - return _VRFCoordinatorV2Plus.ParseMigrationCompleted(log) - case _VRFCoordinatorV2Plus.abi.Events["OwnershipTransferRequested"].ID: - return _VRFCoordinatorV2Plus.ParseOwnershipTransferRequested(log) - case _VRFCoordinatorV2Plus.abi.Events["OwnershipTransferred"].ID: - return _VRFCoordinatorV2Plus.ParseOwnershipTransferred(log) - case _VRFCoordinatorV2Plus.abi.Events["ProvingKeyDeregistered"].ID: - return _VRFCoordinatorV2Plus.ParseProvingKeyDeregistered(log) - case _VRFCoordinatorV2Plus.abi.Events["ProvingKeyRegistered"].ID: - return _VRFCoordinatorV2Plus.ParseProvingKeyRegistered(log) - case _VRFCoordinatorV2Plus.abi.Events["RandomWordsFulfilled"].ID: - return _VRFCoordinatorV2Plus.ParseRandomWordsFulfilled(log) - case _VRFCoordinatorV2Plus.abi.Events["RandomWordsRequested"].ID: - return _VRFCoordinatorV2Plus.ParseRandomWordsRequested(log) - case _VRFCoordinatorV2Plus.abi.Events["SubscriptionCanceled"].ID: - return _VRFCoordinatorV2Plus.ParseSubscriptionCanceled(log) - case _VRFCoordinatorV2Plus.abi.Events["SubscriptionConsumerAdded"].ID: - return _VRFCoordinatorV2Plus.ParseSubscriptionConsumerAdded(log) - case _VRFCoordinatorV2Plus.abi.Events["SubscriptionConsumerRemoved"].ID: - return _VRFCoordinatorV2Plus.ParseSubscriptionConsumerRemoved(log) - case _VRFCoordinatorV2Plus.abi.Events["SubscriptionCreated"].ID: - return _VRFCoordinatorV2Plus.ParseSubscriptionCreated(log) - case _VRFCoordinatorV2Plus.abi.Events["SubscriptionFunded"].ID: - return _VRFCoordinatorV2Plus.ParseSubscriptionFunded(log) - case _VRFCoordinatorV2Plus.abi.Events["SubscriptionFundedWithEth"].ID: - return _VRFCoordinatorV2Plus.ParseSubscriptionFundedWithEth(log) - case _VRFCoordinatorV2Plus.abi.Events["SubscriptionOwnerTransferRequested"].ID: - return _VRFCoordinatorV2Plus.ParseSubscriptionOwnerTransferRequested(log) - case _VRFCoordinatorV2Plus.abi.Events["SubscriptionOwnerTransferred"].ID: - return _VRFCoordinatorV2Plus.ParseSubscriptionOwnerTransferred(log) - - default: - return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) - } -} - -func (VRFCoordinatorV2PlusConfigSet) Topic() common.Hash { - return common.HexToHash("0x777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e78") -} - -func (VRFCoordinatorV2PlusCoordinatorDeregistered) Topic() common.Hash { - return common.HexToHash("0xf80a1a97fd42251f3c33cda98635e7399253033a6774fe37cd3f650b5282af37") -} - -func (VRFCoordinatorV2PlusCoordinatorRegistered) Topic() common.Hash { - return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625") -} - -func (VRFCoordinatorV2PlusEthFundsRecovered) Topic() common.Hash { - return common.HexToHash("0x879c9ea2b9d5345b84ccd12610b032602808517cebdb795007f3dcb4df377317") -} - -func (VRFCoordinatorV2PlusFundsRecovered) Topic() common.Hash { - return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600") -} - -func (VRFCoordinatorV2PlusMigrationCompleted) Topic() common.Hash { - return common.HexToHash("0xd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187") -} - -func (VRFCoordinatorV2PlusOwnershipTransferRequested) Topic() common.Hash { - return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") -} - -func (VRFCoordinatorV2PlusOwnershipTransferred) Topic() common.Hash { - return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") -} - -func (VRFCoordinatorV2PlusProvingKeyDeregistered) Topic() common.Hash { - return common.HexToHash("0x72be339577868f868798bac2c93e52d6f034fef4689a9848996c14ebb7416c0d") -} - -func (VRFCoordinatorV2PlusProvingKeyRegistered) Topic() common.Hash { - return common.HexToHash("0xe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b8") -} - -func (VRFCoordinatorV2PlusRandomWordsFulfilled) Topic() common.Hash { - return common.HexToHash("0x49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa7") -} - -func (VRFCoordinatorV2PlusRandomWordsRequested) Topic() common.Hash { - return common.HexToHash("0xeb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e") -} - -func (VRFCoordinatorV2PlusSubscriptionCanceled) Topic() common.Hash { - return common.HexToHash("0x8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4") -} - -func (VRFCoordinatorV2PlusSubscriptionConsumerAdded) Topic() common.Hash { - return common.HexToHash("0x1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1") -} - -func (VRFCoordinatorV2PlusSubscriptionConsumerRemoved) Topic() common.Hash { - return common.HexToHash("0x32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7") -} - -func (VRFCoordinatorV2PlusSubscriptionCreated) Topic() common.Hash { - return common.HexToHash("0x1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d") -} - -func (VRFCoordinatorV2PlusSubscriptionFunded) Topic() common.Hash { - return common.HexToHash("0x1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a") -} - -func (VRFCoordinatorV2PlusSubscriptionFundedWithEth) Topic() common.Hash { - return common.HexToHash("0x3f1ddc3ab1bdb39001ad76ca51a0e6f57ce6627c69f251d1de41622847721cde") -} - -func (VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested) Topic() common.Hash { - return common.HexToHash("0x21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a1") -} - -func (VRFCoordinatorV2PlusSubscriptionOwnerTransferred) Topic() common.Hash { - return common.HexToHash("0xd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386") -} - -func (_VRFCoordinatorV2Plus *VRFCoordinatorV2Plus) Address() common.Address { - return _VRFCoordinatorV2Plus.address -} - -type VRFCoordinatorV2PlusInterface interface { - BLOCKHASHSTORE(opts *bind.CallOpts) (common.Address, error) - - LINK(opts *bind.CallOpts) (common.Address, error) - - LINKETHFEED(opts *bind.CallOpts) (common.Address, error) - - MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) - - MAXNUMWORDS(opts *bind.CallOpts) (uint32, error) - - 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, - - error) - - HashOfKey(opts *bind.CallOpts, publicKey [2]*big.Int) ([32]byte, error) - - MigrationVersion(opts *bind.CallOpts) (uint8, error) - - Owner(opts *bind.CallOpts) (common.Address, error) - - PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) - - SConfig(opts *bind.CallOpts) (SConfig, - - error) - - SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) - - SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) - - SFeeConfig(opts *bind.CallOpts) (SFeeConfig, - - error) - - SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) - - SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (common.Address, error) - - SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) - - STotalBalance(opts *bind.CallOpts) (*big.Int, error) - - STotalEthBalance(opts *bind.CallOpts) (*big.Int, error) - - AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) - - AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) - - AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) - - CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) - - CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) - - DeregisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) - - DeregisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) - - FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV2PlusRequestCommitment) (*types.Transaction, error) - - FundSubscriptionWithEth(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) - - Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator 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) - - OracleWithdrawEth(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) - - OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) - - RecoverEthFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - - RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) - - RegisterProvingKey(opts *bind.TransactOpts, oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) - - RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) - - RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) - - RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) - - SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV2PlusFeeConfig) (*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) - - FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusConfigSetIterator, error) - - WatchConfigSet(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusConfigSet) (event.Subscription, error) - - ParseConfigSet(log types.Log) (*VRFCoordinatorV2PlusConfigSet, error) - - FilterCoordinatorDeregistered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusCoordinatorDeregisteredIterator, error) - - WatchCoordinatorDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusCoordinatorDeregistered) (event.Subscription, error) - - ParseCoordinatorDeregistered(log types.Log) (*VRFCoordinatorV2PlusCoordinatorDeregistered, error) - - FilterCoordinatorRegistered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusCoordinatorRegisteredIterator, error) - - WatchCoordinatorRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusCoordinatorRegistered) (event.Subscription, error) - - ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorV2PlusCoordinatorRegistered, error) - - FilterEthFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusEthFundsRecoveredIterator, error) - - WatchEthFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusEthFundsRecovered) (event.Subscription, error) - - ParseEthFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusEthFundsRecovered, error) - - FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusFundsRecoveredIterator, error) - - WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusFundsRecovered) (event.Subscription, error) - - ParseFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusFundsRecovered, error) - - FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusMigrationCompletedIterator, error) - - WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusMigrationCompleted) (event.Subscription, error) - - ParseMigrationCompleted(log types.Log) (*VRFCoordinatorV2PlusMigrationCompleted, error) - - FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV2PlusOwnershipTransferRequestedIterator, error) - - WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferRequested(log types.Log) (*VRFCoordinatorV2PlusOwnershipTransferRequested, error) - - FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV2PlusOwnershipTransferredIterator, error) - - WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) - - ParseOwnershipTransferred(log types.Log) (*VRFCoordinatorV2PlusOwnershipTransferred, error) - - FilterProvingKeyDeregistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV2PlusProvingKeyDeregisteredIterator, error) - - WatchProvingKeyDeregistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusProvingKeyDeregistered, oracle []common.Address) (event.Subscription, error) - - ParseProvingKeyDeregistered(log types.Log) (*VRFCoordinatorV2PlusProvingKeyDeregistered, error) - - FilterProvingKeyRegistered(opts *bind.FilterOpts, oracle []common.Address) (*VRFCoordinatorV2PlusProvingKeyRegisteredIterator, error) - - WatchProvingKeyRegistered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusProvingKeyRegistered, oracle []common.Address) (event.Subscription, error) - - ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorV2PlusProvingKeyRegistered, error) - - FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subID []*big.Int) (*VRFCoordinatorV2PlusRandomWordsFulfilledIterator, error) - - WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusRandomWordsFulfilled, requestId []*big.Int, subID []*big.Int) (event.Subscription, error) - - ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorV2PlusRandomWordsFulfilled, error) - - FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*VRFCoordinatorV2PlusRandomWordsRequestedIterator, error) - - WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusRandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) - - ParseRandomWordsRequested(log types.Log) (*VRFCoordinatorV2PlusRandomWordsRequested, error) - - FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionCanceledIterator, error) - - WatchSubscriptionCanceled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionCanceled, subId []*big.Int) (event.Subscription, error) - - ParseSubscriptionCanceled(log types.Log) (*VRFCoordinatorV2PlusSubscriptionCanceled, error) - - FilterSubscriptionConsumerAdded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionConsumerAddedIterator, error) - - WatchSubscriptionConsumerAdded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionConsumerAdded, subId []*big.Int) (event.Subscription, error) - - ParseSubscriptionConsumerAdded(log types.Log) (*VRFCoordinatorV2PlusSubscriptionConsumerAdded, error) - - FilterSubscriptionConsumerRemoved(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionConsumerRemovedIterator, error) - - WatchSubscriptionConsumerRemoved(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionConsumerRemoved, subId []*big.Int) (event.Subscription, error) - - ParseSubscriptionConsumerRemoved(log types.Log) (*VRFCoordinatorV2PlusSubscriptionConsumerRemoved, error) - - FilterSubscriptionCreated(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionCreatedIterator, error) - - WatchSubscriptionCreated(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionCreated, subId []*big.Int) (event.Subscription, error) - - ParseSubscriptionCreated(log types.Log) (*VRFCoordinatorV2PlusSubscriptionCreated, error) - - FilterSubscriptionFunded(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionFundedIterator, error) - - WatchSubscriptionFunded(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionFunded, subId []*big.Int) (event.Subscription, error) - - ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorV2PlusSubscriptionFunded, error) - - FilterSubscriptionFundedWithEth(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionFundedWithEthIterator, error) - - WatchSubscriptionFundedWithEth(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionFundedWithEth, subId []*big.Int) (event.Subscription, error) - - ParseSubscriptionFundedWithEth(log types.Log) (*VRFCoordinatorV2PlusSubscriptionFundedWithEth, error) - - FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionOwnerTransferRequestedIterator, error) - - WatchSubscriptionOwnerTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested, subId []*big.Int) (event.Subscription, error) - - ParseSubscriptionOwnerTransferRequested(log types.Log) (*VRFCoordinatorV2PlusSubscriptionOwnerTransferRequested, error) - - FilterSubscriptionOwnerTransferred(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusSubscriptionOwnerTransferredIterator, error) - - WatchSubscriptionOwnerTransferred(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusSubscriptionOwnerTransferred, subId []*big.Int) (event.Subscription, error) - - ParseSubscriptionOwnerTransferred(log types.Log) (*VRFCoordinatorV2PlusSubscriptionOwnerTransferred, error) - - ParseLog(log types.Log) (generated.AbigenLog, error) - - Address() common.Address -} diff --git a/core/gethwrappers/generated/vrf_coordinator_v2plus_interface/vrf_coordinator_v2plus_interface.go b/core/gethwrappers/generated/vrf_coordinator_v2plus_interface/vrf_coordinator_v2plus_interface.go new file mode 100644 index 0000000000..9ed2e34687 --- /dev/null +++ b/core/gethwrappers/generated/vrf_coordinator_v2plus_interface/vrf_coordinator_v2plus_interface.go @@ -0,0 +1,788 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrf_coordinator_v2plus_interface + +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 IVRFCoordinatorV2PlusInternalProof struct { + Pk [2]*big.Int + Gamma [2]*big.Int + C *big.Int + S *big.Int + Seed *big.Int + UWitness common.Address + CGammaWitness [2]*big.Int + SHashWitness [2]*big.Int + ZInv *big.Int +} + +type IVRFCoordinatorV2PlusInternalRequestCommitment struct { + BlockNum uint64 + SubId *big.Int + CallbackGasLimit uint32 + NumWords uint32 + Sender common.Address + ExtraArgs []byte +} + +type VRFV2PlusClientRandomWordsRequest struct { + KeyHash [32]byte + SubId *big.Int + RequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte +} + +var IVRFCoordinatorV2PlusInternalMetaData = &bind.MetaData{ + ABI: "[{\"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\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structIVRFCoordinatorV2PlusInternal.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\":\"structIVRFCoordinatorV2PlusInternal.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\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestID\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +var IVRFCoordinatorV2PlusInternalABI = IVRFCoordinatorV2PlusInternalMetaData.ABI + +type IVRFCoordinatorV2PlusInternal struct { + address common.Address + abi abi.ABI + IVRFCoordinatorV2PlusInternalCaller + IVRFCoordinatorV2PlusInternalTransactor + IVRFCoordinatorV2PlusInternalFilterer +} + +type IVRFCoordinatorV2PlusInternalCaller struct { + contract *bind.BoundContract +} + +type IVRFCoordinatorV2PlusInternalTransactor struct { + contract *bind.BoundContract +} + +type IVRFCoordinatorV2PlusInternalFilterer struct { + contract *bind.BoundContract +} + +type IVRFCoordinatorV2PlusInternalSession struct { + Contract *IVRFCoordinatorV2PlusInternal + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type IVRFCoordinatorV2PlusInternalCallerSession struct { + Contract *IVRFCoordinatorV2PlusInternalCaller + CallOpts bind.CallOpts +} + +type IVRFCoordinatorV2PlusInternalTransactorSession struct { + Contract *IVRFCoordinatorV2PlusInternalTransactor + TransactOpts bind.TransactOpts +} + +type IVRFCoordinatorV2PlusInternalRaw struct { + Contract *IVRFCoordinatorV2PlusInternal +} + +type IVRFCoordinatorV2PlusInternalCallerRaw struct { + Contract *IVRFCoordinatorV2PlusInternalCaller +} + +type IVRFCoordinatorV2PlusInternalTransactorRaw struct { + Contract *IVRFCoordinatorV2PlusInternalTransactor +} + +func NewIVRFCoordinatorV2PlusInternal(address common.Address, backend bind.ContractBackend) (*IVRFCoordinatorV2PlusInternal, error) { + abi, err := abi.JSON(strings.NewReader(IVRFCoordinatorV2PlusInternalABI)) + if err != nil { + return nil, err + } + contract, err := bindIVRFCoordinatorV2PlusInternal(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &IVRFCoordinatorV2PlusInternal{address: address, abi: abi, IVRFCoordinatorV2PlusInternalCaller: IVRFCoordinatorV2PlusInternalCaller{contract: contract}, IVRFCoordinatorV2PlusInternalTransactor: IVRFCoordinatorV2PlusInternalTransactor{contract: contract}, IVRFCoordinatorV2PlusInternalFilterer: IVRFCoordinatorV2PlusInternalFilterer{contract: contract}}, nil +} + +func NewIVRFCoordinatorV2PlusInternalCaller(address common.Address, caller bind.ContractCaller) (*IVRFCoordinatorV2PlusInternalCaller, error) { + contract, err := bindIVRFCoordinatorV2PlusInternal(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &IVRFCoordinatorV2PlusInternalCaller{contract: contract}, nil +} + +func NewIVRFCoordinatorV2PlusInternalTransactor(address common.Address, transactor bind.ContractTransactor) (*IVRFCoordinatorV2PlusInternalTransactor, error) { + contract, err := bindIVRFCoordinatorV2PlusInternal(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &IVRFCoordinatorV2PlusInternalTransactor{contract: contract}, nil +} + +func NewIVRFCoordinatorV2PlusInternalFilterer(address common.Address, filterer bind.ContractFilterer) (*IVRFCoordinatorV2PlusInternalFilterer, error) { + contract, err := bindIVRFCoordinatorV2PlusInternal(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &IVRFCoordinatorV2PlusInternalFilterer{contract: contract}, nil +} + +func bindIVRFCoordinatorV2PlusInternal(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := IVRFCoordinatorV2PlusInternalMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IVRFCoordinatorV2PlusInternal.Contract.IVRFCoordinatorV2PlusInternalCaller.contract.Call(opts, result, method, params...) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.IVRFCoordinatorV2PlusInternalTransactor.contract.Transfer(opts) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.IVRFCoordinatorV2PlusInternalTransactor.contract.Transact(opts, method, params...) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _IVRFCoordinatorV2PlusInternal.Contract.contract.Call(opts, result, method, params...) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.contract.Transfer(opts) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.contract.Transact(opts, method, params...) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCaller) LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _IVRFCoordinatorV2PlusInternal.contract.Call(opts, &out, "LINK_NATIVE_FEED") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) LINKNATIVEFEED() (common.Address, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.LINKNATIVEFEED(&_IVRFCoordinatorV2PlusInternal.CallOpts) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCallerSession) LINKNATIVEFEED() (common.Address, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.LINKNATIVEFEED(&_IVRFCoordinatorV2PlusInternal.CallOpts) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCaller) GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + var out []interface{} + err := _IVRFCoordinatorV2PlusInternal.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 (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.GetActiveSubscriptionIds(&_IVRFCoordinatorV2PlusInternal.CallOpts, startIndex, maxCount) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCallerSession) GetActiveSubscriptionIds(startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.GetActiveSubscriptionIds(&_IVRFCoordinatorV2PlusInternal.CallOpts, startIndex, maxCount) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCaller) GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) { + var out []interface{} + err := _IVRFCoordinatorV2PlusInternal.contract.Call(opts, &out, "getSubscription", subId) + + outstruct := new(GetSubscription) + if err != nil { + return *outstruct, err + } + + outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.NativeBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + 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 + +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _IVRFCoordinatorV2PlusInternal.Contract.GetSubscription(&_IVRFCoordinatorV2PlusInternal.CallOpts, subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCallerSession) GetSubscription(subId *big.Int) (GetSubscription, + + error) { + return _IVRFCoordinatorV2PlusInternal.Contract.GetSubscription(&_IVRFCoordinatorV2PlusInternal.CallOpts, subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCaller) PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) { + var out []interface{} + err := _IVRFCoordinatorV2PlusInternal.contract.Call(opts, &out, "pendingRequestExists", subId) + + if err != nil { + return *new(bool), err + } + + out0 := *abi.ConvertType(out[0], new(bool)).(*bool) + + return out0, err + +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) PendingRequestExists(subId *big.Int) (bool, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.PendingRequestExists(&_IVRFCoordinatorV2PlusInternal.CallOpts, subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCallerSession) PendingRequestExists(subId *big.Int) (bool, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.PendingRequestExists(&_IVRFCoordinatorV2PlusInternal.CallOpts, subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCaller) SRequestCommitments(opts *bind.CallOpts, requestID *big.Int) ([32]byte, error) { + var out []interface{} + err := _IVRFCoordinatorV2PlusInternal.contract.Call(opts, &out, "s_requestCommitments", requestID) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) SRequestCommitments(requestID *big.Int) ([32]byte, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.SRequestCommitments(&_IVRFCoordinatorV2PlusInternal.CallOpts, requestID) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalCallerSession) SRequestCommitments(requestID *big.Int) ([32]byte, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.SRequestCommitments(&_IVRFCoordinatorV2PlusInternal.CallOpts, requestID) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactor) AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.contract.Transact(opts, "acceptSubscriptionOwnerTransfer", subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.AcceptSubscriptionOwnerTransfer(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorSession) AcceptSubscriptionOwnerTransfer(subId *big.Int) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.AcceptSubscriptionOwnerTransfer(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactor) AddConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.contract.Transact(opts, "addConsumer", subId, consumer) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.AddConsumer(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId, consumer) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorSession) AddConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.AddConsumer(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId, consumer) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactor) CancelSubscription(opts *bind.TransactOpts, subId *big.Int, to common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.contract.Transact(opts, "cancelSubscription", subId, to) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.CancelSubscription(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId, to) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorSession) CancelSubscription(subId *big.Int, to common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.CancelSubscription(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId, to) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactor) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.contract.Transact(opts, "createSubscription") +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) CreateSubscription() (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.CreateSubscription(&_IVRFCoordinatorV2PlusInternal.TransactOpts) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorSession) CreateSubscription() (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.CreateSubscription(&_IVRFCoordinatorV2PlusInternal.TransactOpts) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactor) FulfillRandomWords(opts *bind.TransactOpts, proof IVRFCoordinatorV2PlusInternalProof, rc IVRFCoordinatorV2PlusInternalRequestCommitment) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.contract.Transact(opts, "fulfillRandomWords", proof, rc) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) FulfillRandomWords(proof IVRFCoordinatorV2PlusInternalProof, rc IVRFCoordinatorV2PlusInternalRequestCommitment) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.FulfillRandomWords(&_IVRFCoordinatorV2PlusInternal.TransactOpts, proof, rc) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorSession) FulfillRandomWords(proof IVRFCoordinatorV2PlusInternalProof, rc IVRFCoordinatorV2PlusInternalRequestCommitment) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.FulfillRandomWords(&_IVRFCoordinatorV2PlusInternal.TransactOpts, proof, rc) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactor) FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.contract.Transact(opts, "fundSubscriptionWithNative", subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.FundSubscriptionWithNative(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorSession) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.FundSubscriptionWithNative(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.contract.Transact(opts, "removeConsumer", subId, consumer) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.RemoveConsumer(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId, consumer) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorSession) RemoveConsumer(subId *big.Int, consumer common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.RemoveConsumer(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId, consumer) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactor) RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.contract.Transact(opts, "requestRandomWords", req) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.RequestRandomWords(&_IVRFCoordinatorV2PlusInternal.TransactOpts, req) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorSession) RequestRandomWords(req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.RequestRandomWords(&_IVRFCoordinatorV2PlusInternal.TransactOpts, req) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactor) RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.contract.Transact(opts, "requestSubscriptionOwnerTransfer", subId, newOwner) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.RequestSubscriptionOwnerTransfer(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId, newOwner) +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalTransactorSession) RequestSubscriptionOwnerTransfer(subId *big.Int, newOwner common.Address) (*types.Transaction, error) { + return _IVRFCoordinatorV2PlusInternal.Contract.RequestSubscriptionOwnerTransfer(&_IVRFCoordinatorV2PlusInternal.TransactOpts, subId, newOwner) +} + +type IVRFCoordinatorV2PlusInternalRandomWordsFulfilledIterator struct { + Event *IVRFCoordinatorV2PlusInternalRandomWordsFulfilled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IVRFCoordinatorV2PlusInternalRandomWordsFulfilledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IVRFCoordinatorV2PlusInternalRandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IVRFCoordinatorV2PlusInternalRandomWordsFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IVRFCoordinatorV2PlusInternalRandomWordsFulfilledIterator) Error() error { + return it.fail +} + +func (it *IVRFCoordinatorV2PlusInternalRandomWordsFulfilledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IVRFCoordinatorV2PlusInternalRandomWordsFulfilled struct { + RequestId *big.Int + OutputSeed *big.Int + SubId *big.Int + Payment *big.Int + Success bool + Raw types.Log +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*IVRFCoordinatorV2PlusInternalRandomWordsFulfilledIterator, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _IVRFCoordinatorV2PlusInternal.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) + if err != nil { + return nil, err + } + return &IVRFCoordinatorV2PlusInternalRandomWordsFulfilledIterator{contract: _IVRFCoordinatorV2PlusInternal.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *IVRFCoordinatorV2PlusInternalRandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + logs, sub, err := _IVRFCoordinatorV2PlusInternal.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IVRFCoordinatorV2PlusInternalRandomWordsFulfilled) + if err := _IVRFCoordinatorV2PlusInternal.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalFilterer) ParseRandomWordsFulfilled(log types.Log) (*IVRFCoordinatorV2PlusInternalRandomWordsFulfilled, error) { + event := new(IVRFCoordinatorV2PlusInternalRandomWordsFulfilled) + if err := _IVRFCoordinatorV2PlusInternal.contract.UnpackLog(event, "RandomWordsFulfilled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type IVRFCoordinatorV2PlusInternalRandomWordsRequestedIterator struct { + Event *IVRFCoordinatorV2PlusInternalRandomWordsRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *IVRFCoordinatorV2PlusInternalRandomWordsRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(IVRFCoordinatorV2PlusInternalRandomWordsRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(IVRFCoordinatorV2PlusInternalRandomWordsRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *IVRFCoordinatorV2PlusInternalRandomWordsRequestedIterator) Error() error { + return it.fail +} + +func (it *IVRFCoordinatorV2PlusInternalRandomWordsRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type IVRFCoordinatorV2PlusInternalRandomWordsRequested struct { + KeyHash [32]byte + RequestId *big.Int + PreSeed *big.Int + SubId *big.Int + MinimumRequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte + Sender common.Address + Raw types.Log +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalFilterer) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*IVRFCoordinatorV2PlusInternalRandomWordsRequestedIterator, error) { + + var keyHashRule []interface{} + for _, keyHashItem := range keyHash { + keyHashRule = append(keyHashRule, keyHashItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _IVRFCoordinatorV2PlusInternal.contract.FilterLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) + if err != nil { + return nil, err + } + return &IVRFCoordinatorV2PlusInternalRandomWordsRequestedIterator{contract: _IVRFCoordinatorV2PlusInternal.contract, event: "RandomWordsRequested", logs: logs, sub: sub}, nil +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalFilterer) WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *IVRFCoordinatorV2PlusInternalRandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) { + + var keyHashRule []interface{} + for _, keyHashItem := range keyHash { + keyHashRule = append(keyHashRule, keyHashItem) + } + + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) + } + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _IVRFCoordinatorV2PlusInternal.contract.WatchLogs(opts, "RandomWordsRequested", keyHashRule, subIdRule, senderRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(IVRFCoordinatorV2PlusInternalRandomWordsRequested) + if err := _IVRFCoordinatorV2PlusInternal.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternalFilterer) ParseRandomWordsRequested(log types.Log) (*IVRFCoordinatorV2PlusInternalRandomWordsRequested, error) { + event := new(IVRFCoordinatorV2PlusInternalRandomWordsRequested) + if err := _IVRFCoordinatorV2PlusInternal.contract.UnpackLog(event, "RandomWordsRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetSubscription struct { + Balance *big.Int + NativeBalance *big.Int + ReqCount uint64 + Owner common.Address + Consumers []common.Address +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternal) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _IVRFCoordinatorV2PlusInternal.abi.Events["RandomWordsFulfilled"].ID: + return _IVRFCoordinatorV2PlusInternal.ParseRandomWordsFulfilled(log) + case _IVRFCoordinatorV2PlusInternal.abi.Events["RandomWordsRequested"].ID: + return _IVRFCoordinatorV2PlusInternal.ParseRandomWordsRequested(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (IVRFCoordinatorV2PlusInternalRandomWordsFulfilled) Topic() common.Hash { + return common.HexToHash("0x49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa7") +} + +func (IVRFCoordinatorV2PlusInternalRandomWordsRequested) Topic() common.Hash { + return common.HexToHash("0xeb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e") +} + +func (_IVRFCoordinatorV2PlusInternal *IVRFCoordinatorV2PlusInternal) Address() common.Address { + return _IVRFCoordinatorV2PlusInternal.address +} + +type IVRFCoordinatorV2PlusInternalInterface interface { + LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) + + GetActiveSubscriptionIds(opts *bind.CallOpts, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) + + GetSubscription(opts *bind.CallOpts, subId *big.Int) (GetSubscription, + + error) + + PendingRequestExists(opts *bind.CallOpts, subId *big.Int) (bool, error) + + SRequestCommitments(opts *bind.CallOpts, requestID *big.Int) ([32]byte, error) + + AcceptSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + AddConsumer(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) + + CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) + + FulfillRandomWords(opts *bind.TransactOpts, proof IVRFCoordinatorV2PlusInternalProof, rc IVRFCoordinatorV2PlusInternalRequestCommitment) (*types.Transaction, error) + + FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + + RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) + + RequestRandomWords(opts *bind.TransactOpts, req VRFV2PlusClientRandomWordsRequest) (*types.Transaction, error) + + RequestSubscriptionOwnerTransfer(opts *bind.TransactOpts, subId *big.Int, newOwner common.Address) (*types.Transaction, error) + + FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*IVRFCoordinatorV2PlusInternalRandomWordsFulfilledIterator, error) + + WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *IVRFCoordinatorV2PlusInternalRandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) + + ParseRandomWordsFulfilled(log types.Log) (*IVRFCoordinatorV2PlusInternalRandomWordsFulfilled, error) + + FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (*IVRFCoordinatorV2PlusInternalRandomWordsRequestedIterator, error) + + WatchRandomWordsRequested(opts *bind.WatchOpts, sink chan<- *IVRFCoordinatorV2PlusInternalRandomWordsRequested, keyHash [][32]byte, subId []*big.Int, sender []common.Address) (event.Subscription, error) + + ParseRandomWordsRequested(log types.Log) (*IVRFCoordinatorV2PlusInternalRandomWordsRequested, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} diff --git a/core/gethwrappers/generated/vrf_load_test_with_metrics/vrf_load_test_with_metrics.go b/core/gethwrappers/generated/vrf_load_test_with_metrics/vrf_load_test_with_metrics.go index eb11e58ceb..93d50b72dd 100644 --- a/core/gethwrappers/generated/vrf_load_test_with_metrics/vrf_load_test_with_metrics.go +++ b/core/gethwrappers/generated/vrf_load_test_with_metrics/vrf_load_test_with_metrics.go @@ -32,7 +32,7 @@ var ( var VRFV2LoadTestWithMetricsMetaData = &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\":\"uint64\",\"name\":\"_subId\",\"type\":\"uint64\"},{\"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\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c0604052600060045560006005556103e760065534801561002057600080fd5b506040516110f33803806110f383398101604081905261003f91610199565b6001600160601b0319606082901b1660805233806000816100a75760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100d7576100d7816100ef565b50505060601b6001600160601b03191660a0526101c9565b6001600160a01b0381163314156101485760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161009e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156101ab57600080fd5b81516001600160a01b03811681146101c257600080fd5b9392505050565b60805160601c60a05160601c610ef16102026000396000818161014301526103da0152600081816102b7015261031f0152610ef16000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806379ba509711610097578063d826f88f11610066578063d826f88f1461023f578063d8a4676f1461025e578063dc1670db14610283578063f2fde38b1461028c57600080fd5b806379ba5097146101a55780638da5cb5b146101ad578063a168fa89146101cb578063b1e217491461023657600080fd5b80633b2bcbf1116100d35780633b2bcbf11461013e578063557d2e921461018a578063737144bc1461019357806374dba1241461019c57600080fd5b80631757f11c146100fa5780631fe543e314610116578063271095ef1461012b575b600080fd5b61010360055481565b6040519081526020015b60405180910390f35b610129610124366004610bad565b61029f565b005b610129610139366004610c9c565b61035f565b6101657f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010d565b61010360035481565b61010360045481565b61010360065481565b610129610577565b60005473ffffffffffffffffffffffffffffffffffffffff16610165565b61020c6101d9366004610b7b565b6009602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a00161010d565b61010360075481565b6101296000600481905560058190556103e76006556003819055600255565b61027161026c366004610b7b565b610674565b60405161010d96959493929190610d18565b61010360025481565b61012961029a366004610b3e565b610759565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610351576040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044015b60405180910390fd5b61035b828261076d565b5050565b610367610894565b60005b8161ffff168161ffff16101561056e576040517f5d3b1d300000000000000000000000000000000000000000000000000000000081526004810186905267ffffffffffffffff8816602482015261ffff8716604482015263ffffffff8086166064830152841660848201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690635d3b1d309060a401602060405180830381600087803b15801561043357600080fd5b505af1158015610447573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046b9190610b94565b60078190559050600061047c610917565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a084018390528783526009815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016901515178155905180519495509193909261050a926001850192910190610ab3565b506040820151600282015560608201516003808301919091556080830151600483015560a090920151600590910155805490600061054783610e4d565b9091555050600091825260086020526040909120558061056681610e2b565b91505061036a565b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610348565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000818152600960209081526040808320815160c081018352815460ff16151581526001820180548451818702810187019095528085526060958795869586958695869591949293858401939092908301828280156106f257602002820191906000526020600020905b8154815260200190600101908083116106de575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b610761610894565b61076a816109bd565b50565b6000610777610917565b600084815260086020526040812054919250906107949083610e14565b905060006107a582620f4240610dd7565b90506005548211156107b75760058290555b60065482106107c8576006546107ca565b815b6006556002546107da578061080d565b6002546107e8906001610d84565b816002546004546107f99190610dd7565b6108039190610d84565b61080d9190610d9c565b600455600085815260096020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081178255865161085f939290910191870190610ab3565b506000858152600960205260408120426003820155600501849055600280549161088883610e4d565b91905055505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610348565b565b60004661a4b181148061092c575062066eed81145b156109b657606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561097857600080fd5b505afa15801561098c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b09190610b94565b91505090565b4391505090565b73ffffffffffffffffffffffffffffffffffffffff8116331415610a3d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610348565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610aee579160200282015b82811115610aee578251825591602001919060010190610ad3565b50610afa929150610afe565b5090565b5b80821115610afa5760008155600101610aff565b803561ffff81168114610b2557600080fd5b919050565b803563ffffffff81168114610b2557600080fd5b600060208284031215610b5057600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610b7457600080fd5b9392505050565b600060208284031215610b8d57600080fd5b5035919050565b600060208284031215610ba657600080fd5b5051919050565b60008060408385031215610bc057600080fd5b8235915060208084013567ffffffffffffffff80821115610be057600080fd5b818601915086601f830112610bf457600080fd5b813581811115610c0657610c06610eb5565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610c4957610c49610eb5565b604052828152858101935084860182860187018b1015610c6857600080fd5b600095505b83861015610c8b578035855260019590950194938601938601610c6d565b508096505050505050509250929050565b60008060008060008060c08789031215610cb557600080fd5b863567ffffffffffffffff81168114610ccd57600080fd5b9550610cdb60208801610b13565b945060408701359350610cf060608801610b2a565b9250610cfe60808801610b2a565b9150610d0c60a08801610b13565b90509295509295509295565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b81811015610d5b57845183529383019391830191600101610d3f565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b60008219821115610d9757610d97610e86565b500190565b600082610dd2577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610e0f57610e0f610e86565b500290565b600082821015610e2657610e26610e86565b500390565b600061ffff80831681811415610e4357610e43610e86565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610e7f57610e7f610e86565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", + Bin: "0x60c0604052600060045560006005556103e760065534801561002057600080fd5b5060405161111138038061111183398101604081905261003f91610199565b6001600160601b0319606082901b1660805233806000816100a75760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100d7576100d7816100ef565b50505060601b6001600160601b03191660a0526101c9565b6001600160a01b0381163314156101485760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161009e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156101ab57600080fd5b81516001600160a01b03811681146101c257600080fd5b9392505050565b60805160601c60a05160601c610f0f6102026000396000818161014301526103da0152600081816102b7015261031f0152610f0f6000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c806379ba509711610097578063d826f88f11610066578063d826f88f1461023f578063d8a4676f1461025e578063dc1670db14610283578063f2fde38b1461028c57600080fd5b806379ba5097146101a55780638da5cb5b146101ad578063a168fa89146101cb578063b1e217491461023657600080fd5b80633b2bcbf1116100d35780633b2bcbf11461013e578063557d2e921461018a578063737144bc1461019357806374dba1241461019c57600080fd5b80631757f11c146100fa5780631fe543e314610116578063271095ef1461012b575b600080fd5b61010360055481565b6040519081526020015b60405180910390f35b610129610124366004610bcb565b61029f565b005b610129610139366004610cba565b61035f565b6101657f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010d565b61010360035481565b61010360045481565b61010360065481565b610129610577565b60005473ffffffffffffffffffffffffffffffffffffffff16610165565b61020c6101d9366004610b99565b6009602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a00161010d565b61010360075481565b6101296000600481905560058190556103e76006556003819055600255565b61027161026c366004610b99565b610674565b60405161010d96959493929190610d36565b61010360025481565b61012961029a366004610b5c565b610759565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610351576040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044015b60405180910390fd5b61035b828261076d565b5050565b610367610894565b60005b8161ffff168161ffff16101561056e576040517f5d3b1d300000000000000000000000000000000000000000000000000000000081526004810186905267ffffffffffffffff8816602482015261ffff8716604482015263ffffffff8086166064830152841660848201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690635d3b1d309060a401602060405180830381600087803b15801561043357600080fd5b505af1158015610447573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061046b9190610bb2565b60078190559050600061047c610917565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a084018390528783526009815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016901515178155905180519495509193909261050a926001850192910190610ad1565b506040820151600282015560608201516003808301919091556080830151600483015560a090920151600590910155805490600061054783610e6b565b9091555050600091825260086020526040909120558061056681610e49565b91505061036a565b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610348565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6000818152600960209081526040808320815160c081018352815460ff16151581526001820180548451818702810187019095528085526060958795869586958695869591949293858401939092908301828280156106f257602002820191906000526020600020905b8154815260200190600101908083116106de575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b610761610894565b61076a816109b4565b50565b6000610777610917565b600084815260086020526040812054919250906107949083610e32565b905060006107a582620f4240610df5565b90506005548211156107b75760058290555b60065482106107c8576006546107ca565b815b6006556002546107da578061080d565b6002546107e8906001610da2565b816002546004546107f99190610df5565b6108039190610da2565b61080d9190610dba565b600455600085815260096020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081178255865161085f939290910191870190610ad1565b506000858152600960205260408120426003820155600501849055600280549161088883610e6b565b91905055505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610915576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610348565b565b60004661092381610aaa565b156109ad57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b15801561096f57600080fd5b505afa158015610983573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a79190610bb2565b91505090565b4391505090565b73ffffffffffffffffffffffffffffffffffffffff8116331415610a34576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610348565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061a4b1821480610abe575062066eed82145b80610acb575062066eee82145b92915050565b828054828255906000526020600020908101928215610b0c579160200282015b82811115610b0c578251825591602001919060010190610af1565b50610b18929150610b1c565b5090565b5b80821115610b185760008155600101610b1d565b803561ffff81168114610b4357600080fd5b919050565b803563ffffffff81168114610b4357600080fd5b600060208284031215610b6e57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610b9257600080fd5b9392505050565b600060208284031215610bab57600080fd5b5035919050565b600060208284031215610bc457600080fd5b5051919050565b60008060408385031215610bde57600080fd5b8235915060208084013567ffffffffffffffff80821115610bfe57600080fd5b818601915086601f830112610c1257600080fd5b813581811115610c2457610c24610ed3565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610c6757610c67610ed3565b604052828152858101935084860182860187018b1015610c8657600080fd5b600095505b83861015610ca9578035855260019590950194938601938601610c8b565b508096505050505050509250929050565b60008060008060008060c08789031215610cd357600080fd5b863567ffffffffffffffff81168114610ceb57600080fd5b9550610cf960208801610b31565b945060408701359350610d0e60608801610b48565b9250610d1c60808801610b48565b9150610d2a60a08801610b31565b90509295509295509295565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b81811015610d7957845183529383019391830191600101610d5d565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b60008219821115610db557610db5610ea4565b500190565b600082610df0577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610e2d57610e2d610ea4565b500290565b600082821015610e4457610e44610ea4565b500390565b600061ffff80831681811415610e6157610e61610ea4565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610e9d57610e9d610ea4565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var VRFV2LoadTestWithMetricsABI = VRFV2LoadTestWithMetricsMetaData.ABI diff --git a/core/gethwrappers/generated/vrf_malicious_consumer_v2_plus/vrf_malicious_consumer_v2_plus.go b/core/gethwrappers/generated/vrf_malicious_consumer_v2_plus/vrf_malicious_consumer_v2_plus.go index 4b71dfd50b..b6051bf09f 100644 --- a/core/gethwrappers/generated/vrf_malicious_consumer_v2_plus/vrf_malicious_consumer_v2_plus.go +++ b/core/gethwrappers/generated/vrf_malicious_consumer_v2_plus/vrf_malicious_consumer_v2_plus.go @@ -31,7 +31,7 @@ var ( ) var VRFMaliciousConsumerV2PlusMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"createSubscriptionAndFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"requestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFMigratableCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + 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\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"requestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x60806040523480156200001157600080fd5b5060405162001243380380620012438339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060068054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b61102f80620002146000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80639eccacf611610081578063f08c5daa1161005b578063f08c5daa146101bd578063f2fde38b146101c6578063f6eaffc8146101d957600080fd5b80639eccacf614610181578063cf62c8ab146101a1578063e89e106a146101b457600080fd5b806379ba5097116100b257806379ba5097146101275780638da5cb5b1461012f5780638ea981171461016e57600080fd5b80631fe543e3146100d957806336bfffed146100ee5780635e3b709f14610101575b600080fd5b6100ec6100e7366004610d03565b6101ec565b005b6100ec6100fc366004610c0b565b610272565b61011461010f366004610cd1565b6103aa565b6040519081526020015b60405180910390f35b6100ec6104a0565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011e565b6100ec61017c366004610bf0565b61059d565b6002546101499073ffffffffffffffffffffffffffffffffffffffff1681565b6100ec6101af366004610da7565b6106a8565b61011460045481565b61011460075481565b6100ec6101d4366004610bf0565b6108ae565b6101146101e7366004610cd1565b6108c2565b60025473ffffffffffffffffffffffffffffffffffffffff163314610264576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61026e82826108e3565b5050565b6008546102db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161025b565b60005b815181101561026e57600554600854835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c919085908590811061032157610321610fc4565b60200260200101516040518363ffffffff1660e01b815260040161036592919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561037f57600080fd5b505af1158015610393573d6000803e3d6000fd5b5050505080806103a290610f64565b9150506102de565b60098190556040805160c08101825282815260085460208083019190915260018284018190526207a1206060840152608083015282519081018352600080825260a083019190915260055492517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90610447908490600401610e8c565b602060405180830381600087803b15801561046157600080fd5b505af1158015610475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104999190610cea565b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610521576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161025b565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906105dd575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610661573361060260005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161025b565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6008546107e057600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561071957600080fd5b505af115801561072d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107519190610cea565b60088190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b1580156107c757600080fd5b505af11580156107db573d6000803e3d6000fd5b505050505b6006546005546008546040805160208082019390935281518082039093018352808201918290527f4000aea00000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09361085c93911691869190604401610e40565b602060405180830381600087803b15801561087657600080fd5b505af115801561088a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061026e9190610caf565b6108b66109ee565b6108bf81610a71565b50565b600381815481106108d257600080fd5b600091825260209091200154905081565b5a60075580516108fa906003906020840190610b67565b5060048281556040805160c0810182526009548152600854602080830191909152600182840181905262030d4060608401526080830152825190810183526000815260a082015260055491517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff90921691639b1c385e9161099691859101610e8c565b602060405180830381600087803b1580156109b057600080fd5b505af11580156109c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109e89190610cea565b50505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161025b565b565b73ffffffffffffffffffffffffffffffffffffffff8116331415610af1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161025b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610ba2579160200282015b82811115610ba2578251825591602001919060010190610b87565b50610bae929150610bb2565b5090565b5b80821115610bae5760008155600101610bb3565b803573ffffffffffffffffffffffffffffffffffffffff81168114610beb57600080fd5b919050565b600060208284031215610c0257600080fd5b61049982610bc7565b60006020808385031215610c1e57600080fd5b823567ffffffffffffffff811115610c3557600080fd5b8301601f81018513610c4657600080fd5b8035610c59610c5482610f40565b610ef1565b80828252848201915084840188868560051b8701011115610c7957600080fd5b600094505b83851015610ca357610c8f81610bc7565b835260019490940193918501918501610c7e565b50979650505050505050565b600060208284031215610cc157600080fd5b8151801515811461049957600080fd5b600060208284031215610ce357600080fd5b5035919050565b600060208284031215610cfc57600080fd5b5051919050565b60008060408385031215610d1657600080fd5b8235915060208084013567ffffffffffffffff811115610d3557600080fd5b8401601f81018613610d4657600080fd5b8035610d54610c5482610f40565b80828252848201915084840189868560051b8701011115610d7457600080fd5b600094505b83851015610d97578035835260019490940193918501918501610d79565b5080955050505050509250929050565b600060208284031215610db957600080fd5b81356bffffffffffffffffffffffff8116811461049957600080fd5b6000815180845260005b81811015610dfb57602081850181015186830182015201610ddf565b81811115610e0d576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000610e836060830184610dd5565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610ee960e0840182610dd5565b949350505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610f3857610f38610ff3565b604052919050565b600067ffffffffffffffff821115610f5a57610f5a610ff3565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610fbd577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } 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 index e815f5491d..ce42ddb7d6 100644 --- 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 @@ -32,7 +32,7 @@ var ( 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", + Bin: "0x60a0604052600060055560006006556103e76007553480156200002157600080fd5b50604051620013cc380380620013cc8339810160408190526200004491620002bf565b6001600160601b0319606082901b166080523380600081620000ad5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000e057620000e08162000213565b5050600280546001600160a01b0319166001600160a01b0384169081179091556040805163288688f960e21b8152905191925063a21a23e49160048083019260209291908290030181600087803b1580156200013b57600080fd5b505af115801562000150573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001769190620002f1565b600280546001600160401b03928316600160a01b908102600160a01b600160e01b03198316811793849055604051631cd0704360e21b81529190930490931660048401523060248401526001600160a01b0391821691161790637341c10c90604401600060405180830381600087803b158015620001f357600080fd5b505af115801562000208573d6000803e3d6000fd5b50505050506200031c565b6001600160a01b0381163314156200026e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000a4565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600060208284031215620002d257600080fd5b81516001600160a01b0381168114620002ea57600080fd5b9392505050565b6000602082840312156200030457600080fd5b81516001600160401b0381168114620002ea57600080fd5b60805160601c61108a62000342600039600081816103000152610368015261108a6000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063a168fa8911610097578063d8a4676f11610066578063d8a4676f14610262578063dc1670db14610287578063eb1d28bb14610290578063f2fde38b146102d557600080fd5b8063a168fa89146101bc578063ad603ea214610227578063b1e217491461023a578063d826f88f1461024357600080fd5b8063737144bc116100d3578063737144bc1461018457806374dba1241461018d57806379ba5097146101965780638da5cb5b1461019e57600080fd5b80631757f11c146101055780631fe543e3146101215780633b2bcbf114610136578063557d2e921461017b575b600080fd5b61010e60065481565b6040519081526020015b60405180910390f35b61013461012f366004610dc2565b6102e8565b005b6002546101569073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610118565b61010e60045481565b61010e60055481565b61010e60075481565b6101346103a8565b60005473ffffffffffffffffffffffffffffffffffffffff16610156565b6101fd6101ca366004610d90565b600a602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a001610118565b610134610235366004610d32565b6104a5565b61010e60085481565b6101346000600581905560068190556103e76007556004819055600355565b610275610270366004610d90565b610809565b60405161011896959493929190610eb1565b61010e60035481565b6002546102bc9074010000000000000000000000000000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610118565b6101346102e3366004610cf5565b6108ee565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461039a576040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044015b60405180910390fd5b6103a48282610902565b5050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610429576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610391565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6104ad610a2d565b60005b8161ffff168161ffff1610156106ad576002546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081526004810187905274010000000000000000000000000000000000000000820467ffffffffffffffff16602482015261ffff8816604482015263ffffffff80871660648301528516608482015260009173ffffffffffffffffffffffffffffffffffffffff1690635d3b1d309060a401602060405180830381600087803b15801561057257600080fd5b505af1158015610586573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105aa9190610da9565b6008819055905060006105bb610ab0565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a08401839052878352600a815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169015151781559051805194955091939092610649926001850192910190610c6a565b506040820151600282015560608201516003820155608082015160048083019190915560a090920151600590910155805490600061068683610fe6565b909155505060009182526009602052604090912055806106a581610fc4565b9150506104b0565b506002546040517f9f87fad700000000000000000000000000000000000000000000000000000000815274010000000000000000000000000000000000000000820467ffffffffffffffff16600482015230602482015273ffffffffffffffffffffffffffffffffffffffff90911690639f87fad790604401600060405180830381600087803b15801561074057600080fd5b505af1158015610754573d6000803e3d6000fd5b50506002546040517fd7ae1d3000000000000000000000000000000000000000000000000000000000815274010000000000000000000000000000000000000000820467ffffffffffffffff16600482015233602482015273ffffffffffffffffffffffffffffffffffffffff909116925063d7ae1d309150604401600060405180830381600087803b1580156107ea57600080fd5b505af11580156107fe573d6000803e3d6000fd5b505050505050505050565b6000818152600a60209081526040808320815160c081018352815460ff161515815260018201805484518187028101870190955280855260609587958695869586958695919492938584019390929083018282801561088757602002820191906000526020600020905b815481526020019060010190808311610873575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b6108f6610a2d565b6108ff81610b4d565b50565b600061090c610ab0565b600084815260096020526040812054919250906109299083610fad565b9050600061093a82620f4240610f70565b905060065482111561094c5760068290555b600754821061095d5760075461095f565b815b60075560035461096f57806109a2565b60035461097d906001610f1d565b8160035460055461098e9190610f70565b6109989190610f1d565b6109a29190610f35565b6005556000858152600a6020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117825586516109f4939290910191870190610c6a565b506000858152600a60205260408120426003808301919091556005909101859055805491610a2183610fe6565b91905055505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610aae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610391565b565b600046610abc81610c43565b15610b4657606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b0857600080fd5b505afa158015610b1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b409190610da9565b91505090565b4391505090565b73ffffffffffffffffffffffffffffffffffffffff8116331415610bcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610391565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061a4b1821480610c57575062066eed82145b80610c64575062066eee82145b92915050565b828054828255906000526020600020908101928215610ca5579160200282015b82811115610ca5578251825591602001919060010190610c8a565b50610cb1929150610cb5565b5090565b5b80821115610cb15760008155600101610cb6565b803561ffff81168114610cdc57600080fd5b919050565b803563ffffffff81168114610cdc57600080fd5b600060208284031215610d0757600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610d2b57600080fd5b9392505050565b600080600080600060a08688031215610d4a57600080fd5b610d5386610cca565b945060208601359350610d6860408701610ce1565b9250610d7660608701610ce1565b9150610d8460808701610cca565b90509295509295909350565b600060208284031215610da257600080fd5b5035919050565b600060208284031215610dbb57600080fd5b5051919050565b60008060408385031215610dd557600080fd5b8235915060208084013567ffffffffffffffff80821115610df557600080fd5b818601915086601f830112610e0957600080fd5b813581811115610e1b57610e1b61104e565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610e5e57610e5e61104e565b604052828152858101935084860182860187018b1015610e7d57600080fd5b600095505b83861015610ea0578035855260019590950194938601938601610e82565b508096505050505050509250929050565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b81811015610ef457845183529383019391830191600101610ed8565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b60008219821115610f3057610f3061101f565b500190565b600082610f6b577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610fa857610fa861101f565b500290565b600082821015610fbf57610fbf61101f565b500390565b600061ffff80831681811415610fdc57610fdc61101f565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156110185761101861101f565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var VRFV2OwnerTestConsumerABI = VRFV2OwnerTestConsumerMetaData.ABI diff --git a/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go b/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go index 1c3b30895a..c8971595c5 100644 --- a/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go +++ b/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go @@ -31,8 +31,8 @@ var ( ) var VRFV2PlusLoadTestWithMetricsMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":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\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"_nativePayment\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestCount\",\"type\":\"uint16\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_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\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFMigratableCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080604052600060055560006006556103e760075534801561002057600080fd5b5060405161134738038061134783398101604081905261003f9161019b565b8033806000816100965760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100c6576100c6816100f1565b5050600280546001600160a01b0319166001600160a01b039390931692909217909155506101cb9050565b6001600160a01b03811633141561014a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161008d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156101ad57600080fd5b81516001600160a01b03811681146101c457600080fd5b9392505050565b61116d806101da6000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638ea9811711610097578063d826f88f11610066578063d826f88f14610252578063d8a4676f14610271578063dc1670db14610296578063f2fde38b1461029f57600080fd5b80638ea98117146101ab5780639eccacf6146101be578063a168fa89146101de578063b1e217491461024957600080fd5b8063737144bc116100d3578063737144bc1461015257806374dba1241461015b57806379ba5097146101645780638da5cb5b1461016c57600080fd5b80631757f11c146101055780631fe543e314610121578063557d2e92146101365780636846de201461013f575b600080fd5b61010e60065481565b6040519081526020015b60405180910390f35b61013461012f366004610d66565b6102b2565b005b61010e60045481565b61013461014d366004610e55565b610338565b61010e60055481565b61010e60075481565b610134610565565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610118565b6101346101b9366004610cf7565b610662565b6002546101869073ffffffffffffffffffffffffffffffffffffffff1681565b61021f6101ec366004610d34565b600a602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a001610118565b61010e60085481565b6101346000600581905560068190556103e76007556004819055600355565b61028461027f366004610d34565b61076d565b60405161011896959493929190610ed4565b61010e60035481565b6101346102ad366004610cf7565b610852565b60025473ffffffffffffffffffffffffffffffffffffffff16331461032a576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6103348282610866565b5050565b610340610991565b60005b8161ffff168161ffff16101561055b5760006040518060c001604052808881526020018a81526020018961ffff1681526020018763ffffffff1681526020018563ffffffff1681526020016103a76040518060200160405280891515815250610a14565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610405908590600401610f40565b602060405180830381600087803b15801561041f57600080fd5b505af1158015610433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104579190610d4d565b600881905590506000610468610ad0565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a08401839052878352600a815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690151517815590518051949550919390926104f6926001850192910190610c6c565b506040820151600282015560608201516003820155608082015160048083019190915560a0909201516005909101558054906000610533836110c9565b9091555050600091825260096020526040909120555080610553816110a7565b915050610343565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610321565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906106a2575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561072657336106c760005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610321565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000818152600a60209081526040808320815160c081018352815460ff16151581526001820180548451818702810187019095528085526060958795869586958695869591949293858401939092908301828280156107eb57602002820191906000526020600020905b8154815260200190600101908083116107d7575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b61085a610991565b61086381610b76565b50565b6000610870610ad0565b6000848152600960205260408120549192509061088d9083611090565b9050600061089e82620f4240611053565b90506006548211156108b05760068290555b60075482106108c1576007546108c3565b815b6007556003546108d35780610906565b6003546108e1906001611000565b816003546005546108f29190611053565b6108fc9190611000565b6109069190611018565b6005556000858152600a6020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558651610958939290910191870190610c6c565b506000858152600a60205260408120426003808301919091556005909101859055805491610985836110c9565b91905055505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610321565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610a4d91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b60004661a4b1811480610ae5575062066eed81145b15610b6f57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b3157600080fd5b505afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190610d4d565b91505090565b4391505090565b73ffffffffffffffffffffffffffffffffffffffff8116331415610bf6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610321565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610ca7579160200282015b82811115610ca7578251825591602001919060010190610c8c565b50610cb3929150610cb7565b5090565b5b80821115610cb35760008155600101610cb8565b803561ffff81168114610cde57600080fd5b919050565b803563ffffffff81168114610cde57600080fd5b600060208284031215610d0957600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610d2d57600080fd5b9392505050565b600060208284031215610d4657600080fd5b5035919050565b600060208284031215610d5f57600080fd5b5051919050565b60008060408385031215610d7957600080fd5b8235915060208084013567ffffffffffffffff80821115610d9957600080fd5b818601915086601f830112610dad57600080fd5b813581811115610dbf57610dbf611131565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610e0257610e02611131565b604052828152858101935084860182860187018b1015610e2157600080fd5b600095505b83861015610e44578035855260019590950194938601938601610e26565b508096505050505050509250929050565b600080600080600080600060e0888a031215610e7057600080fd5b87359650610e8060208901610ccc565b955060408801359450610e9560608901610ce3565b935060808801358015158114610eaa57600080fd5b9250610eb860a08901610ce3565b9150610ec660c08901610ccc565b905092959891949750929550565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b81811015610f1757845183529383019391830191600101610efb565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b81811015610fb75782810184015186820161010001528301610f9a565b81811115610fca57600061010083880101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169390930161010001949350505050565b6000821982111561101357611013611102565b500190565b60008261104e577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561108b5761108b611102565b500290565b6000828210156110a2576110a2611102565b500390565b600061ffff808316818114156110bf576110bf611102565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156110fb576110fb611102565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":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\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"_nativePayment\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestCount\",\"type\":\"uint16\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_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\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080604052600060055560006006556103e760075534801561002057600080fd5b5060405161136538038061136583398101604081905261003f9161019b565b8033806000816100965760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100c6576100c6816100f1565b5050600280546001600160a01b0319166001600160a01b039390931692909217909155506101cb9050565b6001600160a01b03811633141561014a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161008d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156101ad57600080fd5b81516001600160a01b03811681146101c457600080fd5b9392505050565b61118b806101da6000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638ea9811711610097578063d826f88f11610066578063d826f88f14610252578063d8a4676f14610271578063dc1670db14610296578063f2fde38b1461029f57600080fd5b80638ea98117146101ab5780639eccacf6146101be578063a168fa89146101de578063b1e217491461024957600080fd5b8063737144bc116100d3578063737144bc1461015257806374dba1241461015b57806379ba5097146101645780638da5cb5b1461016c57600080fd5b80631757f11c146101055780631fe543e314610121578063557d2e92146101365780636846de201461013f575b600080fd5b61010e60065481565b6040519081526020015b60405180910390f35b61013461012f366004610d84565b6102b2565b005b61010e60045481565b61013461014d366004610e73565b610338565b61010e60055481565b61010e60075481565b610134610565565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610118565b6101346101b9366004610d15565b610662565b6002546101869073ffffffffffffffffffffffffffffffffffffffff1681565b61021f6101ec366004610d52565b600a602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a001610118565b61010e60085481565b6101346000600581905560068190556103e76007556004819055600355565b61028461027f366004610d52565b61076d565b60405161011896959493929190610ef2565b61010e60035481565b6101346102ad366004610d15565b610852565b60025473ffffffffffffffffffffffffffffffffffffffff16331461032a576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6103348282610866565b5050565b610340610991565b60005b8161ffff168161ffff16101561055b5760006040518060c001604052808881526020018a81526020018961ffff1681526020018763ffffffff1681526020018563ffffffff1681526020016103a76040518060200160405280891515815250610a14565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610405908590600401610f5e565b602060405180830381600087803b15801561041f57600080fd5b505af1158015610433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104579190610d6b565b600881905590506000610468610ad0565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a08401839052878352600a815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690151517815590518051949550919390926104f6926001850192910190610c8a565b506040820151600282015560608201516003820155608082015160048083019190915560a0909201516005909101558054906000610533836110e7565b9091555050600091825260096020526040909120555080610553816110c5565b915050610343565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610321565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906106a2575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561072657336106c760005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610321565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000818152600a60209081526040808320815160c081018352815460ff16151581526001820180548451818702810187019095528085526060958795869586958695869591949293858401939092908301828280156107eb57602002820191906000526020600020905b8154815260200190600101908083116107d7575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b61085a610991565b61086381610b6d565b50565b6000610870610ad0565b6000848152600960205260408120549192509061088d90836110ae565b9050600061089e82620f4240611071565b90506006548211156108b05760068290555b60075482106108c1576007546108c3565b815b6007556003546108d35780610906565b6003546108e190600161101e565b816003546005546108f29190611071565b6108fc919061101e565b6109069190611036565b6005556000858152600a6020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558651610958939290910191870190610c8a565b506000858152600a60205260408120426003808301919091556005909101859055805491610985836110e7565b91905055505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610321565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610a4d91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b600046610adc81610c63565b15610b6657606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b2857600080fd5b505afa158015610b3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b609190610d6b565b91505090565b4391505090565b73ffffffffffffffffffffffffffffffffffffffff8116331415610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610321565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061a4b1821480610c77575062066eed82145b80610c84575062066eee82145b92915050565b828054828255906000526020600020908101928215610cc5579160200282015b82811115610cc5578251825591602001919060010190610caa565b50610cd1929150610cd5565b5090565b5b80821115610cd15760008155600101610cd6565b803561ffff81168114610cfc57600080fd5b919050565b803563ffffffff81168114610cfc57600080fd5b600060208284031215610d2757600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610d4b57600080fd5b9392505050565b600060208284031215610d6457600080fd5b5035919050565b600060208284031215610d7d57600080fd5b5051919050565b60008060408385031215610d9757600080fd5b8235915060208084013567ffffffffffffffff80821115610db757600080fd5b818601915086601f830112610dcb57600080fd5b813581811115610ddd57610ddd61114f565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610e2057610e2061114f565b604052828152858101935084860182860187018b1015610e3f57600080fd5b600095505b83861015610e62578035855260019590950194938601938601610e44565b508096505050505050509250929050565b600080600080600080600060e0888a031215610e8e57600080fd5b87359650610e9e60208901610cea565b955060408801359450610eb360608901610d01565b935060808801358015158114610ec857600080fd5b9250610ed660a08901610d01565b9150610ee460c08901610cea565b905092959891949750929550565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b81811015610f3557845183529383019391830191600101610f19565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b81811015610fd55782810184015186820161010001528301610fb8565b81811115610fe857600061010083880101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169390930161010001949350505050565b6000821982111561103157611031611120565b500190565b60008261106c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156110a9576110a9611120565b500290565b6000828210156110c0576110c0611120565b500390565b600061ffff808316818114156110dd576110dd611120565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561111957611119611120565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var VRFV2PlusLoadTestWithMetricsABI = VRFV2PlusLoadTestWithMetricsMetaData.ABI diff --git a/core/gethwrappers/generated/vrf_v2plus_single_consumer/vrf_v2plus_single_consumer.go b/core/gethwrappers/generated/vrf_v2plus_single_consumer/vrf_v2plus_single_consumer.go index adc4bf2f4f..6e0f5f3ccd 100644 --- a/core/gethwrappers/generated/vrf_v2plus_single_consumer/vrf_v2plus_single_consumer.go +++ b/core/gethwrappers/generated/vrf_v2plus_single_consumer/vrf_v2plus_single_consumer.go @@ -31,7 +31,7 @@ var ( ) var VRFV2PlusSingleConsumerExampleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"fundAndRequestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestConfig\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFMigratableCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"subscribe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"unsubscribe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"fundAndRequestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestConfig\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"subscribe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"unsubscribe\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x60806040523480156200001157600080fd5b506040516200186338038062001863833981016040819052620000349162000464565b8633806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620001b4565b5050600280546001600160a01b03199081166001600160a01b03948516179091556003805482168b8516179055600480548216938a169390931790925550600b80543392169190911790556040805160c081018252600080825263ffffffff8881166020840181905261ffff8916948401859052908716606084018190526080840187905285151560a09094018490526005929092556006805465ffffffffffff19169091176401000000009094029390931763ffffffff60301b191666010000000000009091021790915560078390556008805460ff19169091179055620001a762000260565b5050505050505062000530565b6001600160a01b0381163314156200020f5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6200026a620003d4565b604080516001808252818301909252600091602080830190803683370190505090503081600081518110620002a357620002a36200051a565b6001600160a01b039283166020918202929092018101919091526003546040805163288688f960e21b81529051919093169263a21a23e49260048083019391928290030181600087803b158015620002fa57600080fd5b505af11580156200030f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000335919062000500565b600581905560035482516001600160a01b039091169163bec4c08c9184906000906200036557620003656200051a565b60200260200101516040518363ffffffff1660e01b81526004016200039d9291909182526001600160a01b0316602082015260400190565b600060405180830381600087803b158015620003b857600080fd5b505af1158015620003cd573d6000803e3d6000fd5b5050505050565b6000546001600160a01b03163314620004305760405162461bcd60e51b815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640162000083565b565b80516001600160a01b03811681146200044a57600080fd5b919050565b805163ffffffff811681146200044a57600080fd5b600080600080600080600060e0888a0312156200048057600080fd5b6200048b8862000432565b96506200049b6020890162000432565b9550620004ab604089016200044f565b9450606088015161ffff81168114620004c357600080fd5b9350620004d3608089016200044f565b925060a0880151915060c08801518015158114620004f057600080fd5b8091505092959891949750929550565b6000602082840312156200051357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b61132380620005406000396000f3fe608060405234801561001057600080fd5b50600436106100f45760003560e01c80638da5cb5b11610097578063e0c8628911610066578063e0c862891461025c578063e89e106a14610264578063f2fde38b1461027b578063f6eaffc81461028e57600080fd5b80638da5cb5b146101e25780638ea98117146102215780638f449a05146102345780639eccacf61461023c57600080fd5b80637262561c116100d35780637262561c1461013457806379ba5097146101475780637db9263f1461014f57806386850e93146101cf57600080fd5b8062f714ce146100f95780631fe543e31461010e5780636fd700bb14610121575b600080fd5b61010c61010736600461108f565b6102a1565b005b61010c61011c3660046110bb565b61035c565b61010c61012f36600461105d565b6103e2565b61010c610142366004611019565b610618565b61010c6106b8565b60055460065460075460085461018b939263ffffffff8082169361ffff6401000000008404169366010000000000009093049091169160ff1686565b6040805196875263ffffffff958616602088015261ffff90941693860193909352921660608401526080830191909152151560a082015260c0015b60405180910390f35b61010c6101dd36600461105d565b6107b5565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c6565b61010c61022f366004611019565b61088b565b61010c610996565b6002546101fc9073ffffffffffffffffffffffffffffffffffffffff1681565b61010c610b3b565b61026d600a5481565b6040519081526020016101c6565b61010c610289366004611019565b610ca8565b61026d61029c36600461105d565b610cbc565b6102a9610cdd565b600480546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116938201939093526024810185905291169063a9059cbb90604401602060405180830381600087803b15801561031f57600080fd5b505af1158015610333573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610357919061103b565b505050565b60025473ffffffffffffffffffffffffffffffffffffffff1633146103d4576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6103de8282610d60565b5050565b6103ea610cdd565b6040805160c08101825260055480825260065463ffffffff808216602080860191909152640100000000830461ffff16858701526601000000000000909204166060840152600754608084015260085460ff16151560a0840152600454600354855192830193909352929373ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918691016040516020818303038152906040526040518463ffffffff1660e01b81526004016104a693929190611215565b602060405180830381600087803b1580156104c057600080fd5b505af11580156104d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104f8919061103b565b5060006040518060c001604052808360800151815260200183600001518152602001836040015161ffff168152602001836020015163ffffffff168152602001836060015163ffffffff16815260200161056560405180602001604052808660a001511515815250610dde565b90526003546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e906105be908490600401611253565b602060405180830381600087803b1580156105d857600080fd5b505af11580156105ec573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106109190611076565b600a55505050565b610620610cdd565b6003546005546040517f0ae09540000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff838116602483015290911690630ae0954090604401600060405180830381600087803b15801561069857600080fd5b505af11580156106ac573d6000803e3d6000fd5b50506000600555505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610739576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016103cb565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6107bd610cdd565b6004546003546005546040805160208082019390935281518082039093018352808201918290527f4000aea00000000000000000000000000000000000000000000000000000000090915273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09361083993911691869190604401611215565b602060405180830381600087803b15801561085357600080fd5b505af1158015610867573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103de919061103b565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906108cb575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561094f57336108f060005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529190911660448201526064016103cb565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61099e610cdd565b6040805160018082528183019092526000916020808301908036833701905050905030816000815181106109d4576109d46112b8565b73ffffffffffffffffffffffffffffffffffffffff928316602091820292909201810191909152600354604080517fa21a23e40000000000000000000000000000000000000000000000000000000081529051919093169263a21a23e49260048083019391928290030181600087803b158015610a5057600080fd5b505af1158015610a64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a889190611076565b6005819055600354825173ffffffffffffffffffffffffffffffffffffffff9091169163bec4c08c918490600090610ac257610ac26112b8565b60200260200101516040518363ffffffff1660e01b8152600401610b0692919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b158015610b2057600080fd5b505af1158015610b34573d6000803e3d6000fd5b5050505050565b610b43610cdd565b6040805160c08082018352600554825260065463ffffffff808216602080860191825261ffff640100000000850481168789019081526601000000000000909504841660608089019182526007546080808b0191825260085460ff16151560a0808d019182528d519b8c018e5292518b528b518b8801529851909416898c0152945186169088015251909316928501929092528551918201909552905115158152919260009290820190610bf690610dde565b90526003546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90610c4f908490600401611253565b602060405180830381600087803b158015610c6957600080fd5b505af1158015610c7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca19190611076565b600a555050565b610cb0610cdd565b610cb981610e9a565b50565b60098181548110610ccc57600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610d5e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016103cb565b565b600a548214610dcb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016103cb565b8051610357906009906020840190610f90565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610e1791511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b73ffffffffffffffffffffffffffffffffffffffff8116331415610f1a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016103cb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610fcb579160200282015b82811115610fcb578251825591602001919060010190610fb0565b50610fd7929150610fdb565b5090565b5b80821115610fd75760008155600101610fdc565b803573ffffffffffffffffffffffffffffffffffffffff8116811461101457600080fd5b919050565b60006020828403121561102b57600080fd5b61103482610ff0565b9392505050565b60006020828403121561104d57600080fd5b8151801515811461103457600080fd5b60006020828403121561106f57600080fd5b5035919050565b60006020828403121561108857600080fd5b5051919050565b600080604083850312156110a257600080fd5b823591506110b260208401610ff0565b90509250929050565b600080604083850312156110ce57600080fd5b8235915060208084013567ffffffffffffffff808211156110ee57600080fd5b818601915086601f83011261110257600080fd5b813581811115611114576111146112e7565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715611157576111576112e7565b604052828152858101935084860182860187018b101561117657600080fd5b600095505b8386101561119957803585526001959095019493860193860161117b565b508096505050505050509250929050565b6000815180845260005b818110156111d0576020818501810151868301820152016111b4565b818111156111e2576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff8416815282602082015260606040820152600061124a60608301846111aa565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c0808401526112b060e08401826111aa565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } diff --git a/core/gethwrappers/generated/vrf_v2plus_sub_owner/vrf_v2plus_sub_owner.go b/core/gethwrappers/generated/vrf_v2plus_sub_owner/vrf_v2plus_sub_owner.go index f422ed29bc..34108bea1d 100644 --- a/core/gethwrappers/generated/vrf_v2plus_sub_owner/vrf_v2plus_sub_owner.go +++ b/core/gethwrappers/generated/vrf_v2plus_sub_owner/vrf_v2plus_sub_owner.go @@ -31,7 +31,7 @@ var ( ) var VRFV2PlusExternalSubOwnerExampleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFMigratableCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + 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\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x608060405234801561001057600080fd5b50604051610d77380380610d7783398101604081905261002f916101d0565b8133806000816100865760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100b6576100b68161010a565b5050600280546001600160a01b039384166001600160a01b03199182161790915560038054958416958216959095179094555060048054929091169183169190911790556007805490911633179055610203565b6001600160a01b0381163314156101635760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161007d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146101cb57600080fd5b919050565b600080604083850312156101e357600080fd5b6101ec836101b4565b91506101fa602084016101b4565b90509250929050565b610b65806102126000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c80638ea9811711610076578063e89e106a1161005b578063e89e106a1461014f578063f2fde38b14610166578063f6eaffc81461017957600080fd5b80638ea981171461011c5780639eccacf61461012f57600080fd5b80631fe543e3146100a85780635b6c5de8146100bd57806379ba5097146100d05780638da5cb5b146100d8575b600080fd5b6100bb6100b6366004610902565b61018c565b005b6100bb6100cb3660046109f1565b610212565b6100bb610325565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100bb61012a366004610893565b610422565b6002546100f29073ffffffffffffffffffffffffffffffffffffffff1681565b61015860065481565b604051908152602001610113565b6100bb610174366004610893565b61052d565b6101586101873660046108d0565b610541565b60025473ffffffffffffffffffffffffffffffffffffffff163314610204576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b61020e8282610562565b5050565b61021a6105e5565b60006040518060c001604052808481526020018881526020018661ffff1681526020018763ffffffff1681526020018563ffffffff16815260200161026e6040518060200160405280861515815250610668565b90526003546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e906102c7908490600401610a69565b602060405180830381600087803b1580156102e157600080fd5b505af11580156102f5573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031991906108e9565b60065550505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146103a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016101fb565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610462575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156104e6573361048760005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff938416600482015291831660248301529190911660448201526064016101fb565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6105356105e5565b61053e81610724565b50565b6005818154811061055157600080fd5b600091825260209091200154905081565b60065482146105cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f727265637400000000000000000060448201526064016101fb565b80516105e090600590602084019061081a565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610666576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016101fb565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016106a191511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b73ffffffffffffffffffffffffffffffffffffffff81163314156107a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016101fb565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215610855579160200282015b8281111561085557825182559160200191906001019061083a565b50610861929150610865565b5090565b5b808211156108615760008155600101610866565b803563ffffffff8116811461088e57600080fd5b919050565b6000602082840312156108a557600080fd5b813573ffffffffffffffffffffffffffffffffffffffff811681146108c957600080fd5b9392505050565b6000602082840312156108e257600080fd5b5035919050565b6000602082840312156108fb57600080fd5b5051919050565b6000806040838503121561091557600080fd5b8235915060208084013567ffffffffffffffff8082111561093557600080fd5b818601915086601f83011261094957600080fd5b81358181111561095b5761095b610b29565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561099e5761099e610b29565b604052828152858101935084860182860187018b10156109bd57600080fd5b600095505b838610156109e05780358552600195909501949386019386016109c2565b508096505050505050509250929050565b60008060008060008060c08789031215610a0a57600080fd5b86359550610a1a6020880161087a565b9450604087013561ffff81168114610a3157600080fd5b9350610a3f6060880161087a565b92506080870135915060a08701358015158114610a5b57600080fd5b809150509295509295509295565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b81811015610ae05782810184015186820161010001528301610ac3565b81811115610af357600061010083880101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169390930161010001949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } diff --git a/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go b/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go index fdb64cecc4..b42d110b85 100644 --- a/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go +++ b/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go @@ -31,8 +31,8 @@ var ( ) type VRFCoordinatorV2PlusUpgradedVersionFeeConfig struct { - FulfillmentFlatFeeLinkPPM uint32 - FulfillmentFlatFeeEthPPM uint32 + FulfillmentFlatFeeLinkPPM uint32 + FulfillmentFlatFeeNativePPM uint32 } type VRFCoordinatorV2PlusUpgradedVersionRequestCommitment struct { @@ -66,8 +66,8 @@ type VRFV2PlusClientRandomWordsRequest struct { } var VRFCoordinatorV2PlusUpgradedVersionMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendEther\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"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\":\"uint256\",\"name\":\"transferredValue\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"expectedValue\",\"type\":\"uint96\"}],\"name\":\"InvalidNativeBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"expectedVersion\",\"type\":\"uint8\"}],\"name\":\"InvalidVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIDCollisionFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeEthPPM\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinatorV2PlusUpgradedVersion.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"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\":\"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\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2PlusUpgradedVersion.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"}],\"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\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"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\":\"structVRFCoordinatorV2PlusUpgradedVersion.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: "0x60a06040523480156200001157600080fd5b50604051620060b9380380620060b9833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615ede620001db600039600081816104c401526136f60152615ede6000f3fe6080604052600436106102015760003560e01c806201229114610206578063043bd6ae14610233578063088070f5146102575780630ae09540146102d757806315c48b84146102f95780631b6b6d2314610321578063294daa491461034e578063330987b31461036a578063405b84fa146103a257806340d6bb82146103c257806341af6c87146103ed57806346d8d4861461041d57806357133e641461043d5780635d06b4ab1461045d57806364d51a2a1461047d57806366316d8d14610492578063689c4517146104b25780636b6feccc146104e65780636f64f03f1461051c57806379ba50971461053c57806386fe91c7146105515780638da5cb5b146105715780639b1c385e1461058f5780639d40a6fd146105af578063a21a23e4146105dc578063a4c0ed36146105f1578063a8cb447b14610611578063aa433aff14610631578063ad17836114610651578063aefb212f14610671578063b08c87951461069e578063b2a7cac5146106be578063bec4c08c146106de578063caf70c4a146106fe578063cb6317971461071e578063ce3f47191461073e578063d98e620e14610751578063da2f261014610771578063dac83d29146107a7578063dc311dd3146107c7578063e72f6e30146107f8578063e8509bff14610818578063e95704bd1461082b578063ee9d2d3814610852578063f2fde38b1461087f575b600080fd5b34801561021257600080fd5b5061021b61089f565b60405161022a939291906159d4565b60405180910390f35b34801561023f57600080fd5b5061024960115481565b60405190815260200161022a565b34801561026357600080fd5b50600d5461029f9061ffff81169063ffffffff62010000820481169160ff600160301b82041691600160381b8204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a00161022a565b3480156102e357600080fd5b506102f76102f2366004615655565b61091b565b005b34801561030557600080fd5b5061030e60c881565b60405161ffff909116815260200161022a565b34801561032d57600080fd5b50600254610341906001600160a01b031681565b60405161022a9190615878565b34801561035a57600080fd5b506040516001815260200161022a565b34801561037657600080fd5b5061038a6103853660046153c3565b6109e9565b6040516001600160601b03909116815260200161022a565b3480156103ae57600080fd5b506102f76103bd366004615655565b610ec4565b3480156103ce57600080fd5b506103d86101f481565b60405163ffffffff909116815260200161022a565b3480156103f957600080fd5b5061040d610408366004615305565b6112af565b604051901515815260200161022a565b34801561042957600080fd5b506102f76104383660046151c7565b611450565b34801561044957600080fd5b506102f76104583660046151fc565b6115cd565b34801561046957600080fd5b506102f76104783660046151aa565b61162d565b34801561048957600080fd5b5061030e606481565b34801561049e57600080fd5b506102f76104ad3660046151c7565b6116e4565b3480156104be57600080fd5b506103417f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f257600080fd5b5060125461050e9063ffffffff80821691600160201b90041682565b60405161022a929190615b56565b34801561052857600080fd5b506102f7610537366004615235565b6118ac565b34801561054857600080fd5b506102f76119b3565b34801561055d57600080fd5b50600a5461038a906001600160601b031681565b34801561057d57600080fd5b506000546001600160a01b0316610341565b34801561059b57600080fd5b506102496105aa3660046154a0565b611a5d565b3480156105bb57600080fd5b506007546105cf906001600160401b031681565b60405161022a9190615b6d565b3480156105e857600080fd5b50610249611dcd565b3480156105fd57600080fd5b506102f761060c366004615271565b61201b565b34801561061d57600080fd5b506102f761062c3660046151aa565b6121b8565b34801561063d57600080fd5b506102f761064c366004615305565b6122c4565b34801561065d57600080fd5b50600354610341906001600160a01b031681565b34801561067d57600080fd5b5061069161068c36600461567a565b612327565b60405161022a91906158ef565b3480156106aa57600080fd5b506102f76106b93660046155b7565b612428565b3480156106ca57600080fd5b506102f76106d9366004615305565b61259c565b3480156106ea57600080fd5b506102f76106f9366004615655565b6126cc565b34801561070a57600080fd5b506102496107193660046152cc565b612863565b34801561072a57600080fd5b506102f7610739366004615655565b612893565b6102f761074c366004615337565b612b80565b34801561075d57600080fd5b5061024961076c366004615305565b612e91565b34801561077d57600080fd5b5061034161078c366004615305565b600e602052600090815260409020546001600160a01b031681565b3480156107b357600080fd5b506102f76107c2366004615655565b612eb2565b3480156107d357600080fd5b506107e76107e2366004615305565b612fc2565b60405161022a959493929190615b81565b34801561080457600080fd5b506102f76108133660046151aa565b6130bd565b6102f7610826366004615305565b613298565b34801561083757600080fd5b50600a5461038a90600160601b90046001600160601b031681565b34801561085e57600080fd5b5061024961086d366004615305565b60106020526000908152604090205481565b34801561088b57600080fd5b506102f761089a3660046151aa565b6133d0565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff1693919283919083018282801561090957602002820191906000526020600020905b8154815260200190600101908083116108f5575b50505050509050925092509250909192565b60008281526005602052604090205482906001600160a01b03168061095357604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146109875780604051636c51fda960e11b815260040161097e9190615878565b60405180910390fd5b600d54600160301b900460ff16156109b25760405163769dd35360e11b815260040160405180910390fd5b6109bb846112af565b156109d957604051631685ecdd60e31b815260040160405180910390fd5b6109e384846133e1565b50505050565b600d54600090600160301b900460ff1615610a175760405163769dd35360e11b815260040160405180910390fd5b60005a90506000610a28858561359c565b90506000846060015163ffffffff166001600160401b03811115610a4e57610a4e615e98565b604051908082528060200260200182016040528015610a77578160200160208202803683370190505b50905060005b856060015163ffffffff16811015610aee57826040015181604051602001610aa6929190615902565b6040516020818303038152906040528051906020012060001c828281518110610ad157610ad1615e82565b602090810291909101015280610ae681615dea565b915050610a7d565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b91610b2691908690602401615a5e565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805460ff60301b1916600160301b179055908801516080890151919250600091610b8b9163ffffffff16908461380f565b600d805460ff60301b19169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b0316610bcb816001615cfb565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a01518051610c1890600190615d7b565b81518110610c2857610c28615e82565b602091010151600d5460f89190911c6001149150600090610c59908a90600160581b900463ffffffff163a8561385d565b90508115610d62576020808c01516000908152600690915260409020546001600160601b03808316600160601b909204161015610ca957604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c90610ce0908490600160601b90046001600160601b0316615d92565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c909152812080548594509092610d3991859116615d26565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610e4e565b6020808c01516000908152600690915260409020546001600160601b0380831691161015610da357604051631e9acf1760e31b815260040160405180910390fd5b6020808c015160009081526006909152604081208054839290610dd09084906001600160601b0316615d92565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b909152812080548594509092610e2991859116615d26565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051610eab939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b600d54600160301b900460ff1615610eef5760405163769dd35360e11b815260040160405180910390fd5b610ef8816138ac565b610f175780604051635428d44960e01b815260040161097e9190615878565b600080600080610f2686612fc2565b945094505093509350336001600160a01b0316826001600160a01b031614610f895760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b604482015260640161097e565b610f92866112af565b15610fd85760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b604482015260640161097e565b60006040518060c00160405280610fed600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016110419190615941565b604051602081830303815290604052905061105b88613916565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b0388169061109490859060040161592e565b6000604051808303818588803b1580156110ad57600080fd5b505af11580156110c1573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506110ea905057506001600160601b03861615155b156111b45760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611121908a908a906004016158bf565b602060405180830381600087803b15801561113b57600080fd5b505af115801561114f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117391906152e8565b6111b45760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b604482015260640161097e565b600d805460ff60301b1916600160301b17905560005b835181101561125d578381815181106111e5576111e5615e82565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b81526004016112189190615878565b600060405180830381600087803b15801561123257600080fd5b505af1158015611246573d6000803e3d6000fd5b50505050808061125590615dea565b9150506111ca565b50600d805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be41879061129d9089908b9061588c565b60405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561133957602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161131b575b505050505081525050905060005b8160400151518110156114465760005b600f548110156114335760006113fc600f838154811061137957611379615e82565b90600052602060002001548560400151858151811061139a5761139a615e82565b60200260200101518860046000896040015189815181106113bd576113bd615e82565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208d82529092529020546001600160401b0316613b64565b50600081815260106020526040902054909150156114205750600195945050505050565b508061142b81615dea565b915050611357565b508061143e81615dea565b915050611347565b5060009392505050565b600d54600160301b900460ff161561147b5760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b03808316911610156114b757604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c6020526040812080548392906114df9084906001600160601b0316615d92565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b03166115279190615d92565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d80600081146115a1576040519150601f19603f3d011682016040523d82523d6000602084013e6115a6565b606091505b50509050806115c857604051630dcf35db60e41b815260040160405180910390fd5b505050565b6115d5613bed565b6002546001600160a01b0316156115ff57604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b611635613bed565b61163e816138ac565b1561165e578060405163ac8a27ef60e01b815260040161097e9190615878565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625906116d9908390615878565b60405180910390a150565b600d54600160301b900460ff161561170f5760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b03166117385760405163c1f0c0a160e01b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b038083169116101561177457604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b60205260408120805483929061179c9084906001600160601b0316615d92565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166117e49190615d92565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061183990859085906004016158bf565b602060405180830381600087803b15801561185357600080fd5b505af1158015611867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188b91906152e8565b6118a857604051631e9acf1760e31b815260040160405180910390fd5b5050565b6118b4613bed565b6040805180820182526000916118e3919084906002908390839080828437600092019190915250612863915050565b6000818152600e60205260409020549091506001600160a01b03161561191f57604051634a0b8fa760e01b81526004810182905260240161097e565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b8910160405180910390a2505050565b6001546001600160a01b03163314611a065760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b604482015260640161097e565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b600d54600090600160301b900460ff1615611a8b5760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b0316611ac657604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680611b13578260200135336040516379bfd40160e01b815260040161097e929190615a33565b600d5461ffff16611b2a606085016040860161559c565b61ffff161080611b4d575060c8611b47606085016040860161559c565b61ffff16115b15611b8757611b62606084016040850161559c565b600d5460405163539c34bb60e11b815261097e929161ffff169060c8906004016159b6565b600d5462010000900463ffffffff16611ba6608085016060860161569c565b63ffffffff161115611bec57611bc2608084016060850161569c565b600d54604051637aebf00f60e11b815261097e929162010000900463ffffffff1690600401615b56565b6101f4611bff60a085016080860161569c565b63ffffffff161115611c3957611c1b60a084016080850161569c565b6101f46040516311ce1afb60e21b815260040161097e929190615b56565b6000611c46826001615cfb565b9050600080611c5c863533602089013586613b64565b90925090506000611c78611c7360a0890189615bd6565b613c42565b90506000611c8582613cbf565b905083611c90613d30565b60208a0135611ca560808c0160608d0161569c565b611cb560a08d0160808e0161569c565b3386604051602001611ccd9796959493929190615ab6565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190611d44919061559c565b8e6060016020810190611d57919061569c565b8f6080016020810190611d6a919061569c565b89604051611d7d96959493929190615a77565b60405180910390a45050336000908152600460209081526040808320898301358452909152902080546001600160401b0319166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff1615611dfb5760405163769dd35360e11b815260040160405180910390fd5b600033611e09600143615d7b565b600754604051606093841b6001600160601b03199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b03909116906000611e8383615e05565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b03811115611ec257611ec2615e98565b604051908082528060200260200182016040528015611eeb578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b039283161783559251600183018054909416911617909155925180519495509093611fcc9260028501920190614e1b565b50611fdc91506008905083613dc9565b50817f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d3360405161200d9190615878565b60405180910390a250905090565b600d54600160301b900460ff16156120465760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b03163314612071576040516344b0e3c360e01b815260040160405180910390fd5b6020811461209257604051638129bbcd60e01b815260040160405180910390fd5b60006120a082840184615305565b6000818152600560205260409020549091506001600160a01b03166120d857604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b0316918691906120ff8385615d26565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166121479190615d26565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a82878461219a9190615ce3565b6040516121a8929190615902565b60405180910390a2505050505050565b6121c0613bed565b600a544790600160601b90046001600160601b0316818111156121fa5780826040516354ced18160e11b815260040161097e929190615902565b818110156115c857600061220e8284615d7b565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d806000811461225d576040519150601f19603f3d011682016040523d82523d6000602084013e612262565b606091505b505090508061228457604051630dcf35db60e41b815260040160405180910390fd5b7f879c9ea2b9d5345b84ccd12610b032602808517cebdb795007f3dcb4df37731785836040516122b592919061588c565b60405180910390a15050505050565b6122cc613bed565b6000818152600560205260409020546001600160a01b031661230157604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020546123249082906001600160a01b03166133e1565b50565b606060006123356008613dd5565b905080841061235757604051631390f2a160e01b815260040160405180910390fd5b60006123638486615ce3565b905081811180612371575083155b61237b578061237d565b815b9050600061238b8683615d7b565b6001600160401b038111156123a2576123a2615e98565b6040519080825280602002602001820160405280156123cb578160200160208202803683370190505b50905060005b815181101561241e576123ef6123e78883615ce3565b600890613ddf565b82828151811061240157612401615e82565b60209081029190910101528061241681615dea565b9150506123d1565b5095945050505050565b612430613bed565b60c861ffff8716111561245d57858660c860405163539c34bb60e11b815260040161097e939291906159b6565b60008213612481576040516321ea67b360e11b81526004810183905260240161097e565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff1916881762010000870217600160301b600160781b031916600160381b850263ffffffff60581b191617600160581b83021790558a51601280548d8701519289166001600160401b031990911617600160201b92891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff16156125c75760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b03166125fc57604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612653576000818152600560205260409081902060010154905163d084e97560e01b815261097e916001600160a01b031690600401615878565b6000818152600560205260409081902080546001600160a01b031980821633908117845560019093018054909116905591516001600160a01b039092169183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386916126c09185916158a5565b60405180910390a25050565b60008281526005602052604090205482906001600160a01b03168061270457604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461272f5780604051636c51fda960e11b815260040161097e9190615878565b600d54600160301b900460ff161561275a5760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600201546064141561278d576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316156127c4576109e3565b6001600160a01b0383166000818152600460209081526040808320888452825280832080546001600160401b031916600190811790915560058352818420600201805491820181558452919092200180546001600160a01b0319169092179091555184907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e190612855908690615878565b60405180910390a250505050565b60008160405160200161287691906158e1565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b0316806128cb57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146128f65780604051636c51fda960e11b815260040161097e9190615878565b600d54600160301b900460ff16156129215760405163769dd35360e11b815260040160405180910390fd5b61292a846112af565b1561294857604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b03166129965783836040516379bfd40160e01b815260040161097e929190615a33565b6000848152600560209081526040808320600201805482518185028101850190935280835291929091908301828280156129f957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116129db575b50505050509050600060018251612a109190615d7b565b905060005b8251811015612b1c57856001600160a01b0316838281518110612a3a57612a3a615e82565b60200260200101516001600160a01b03161415612b0a576000838381518110612a6557612a65615e82565b6020026020010151905080600560008a81526020019081526020016000206002018381548110612a9757612a97615e82565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255898152600590915260409020600201805480612ae257612ae2615e6c565b600082815260209020810160001990810180546001600160a01b031916905501905550612b1c565b80612b1481615dea565b915050612a15565b506001600160a01b03851660009081526004602090815260408083208984529091529081902080546001600160401b03191690555186907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7906121a8908890615878565b6000612b8e828401846154da565b9050806000015160ff16600114612bc757805160405163237d181f60e21b815260ff90911660048201526001602482015260440161097e565b8060a001516001600160601b03163414612c0b5760a08101516040516306acf13560e41b81523460048201526001600160601b03909116602482015260440161097e565b6020808201516000908152600590915260409020546001600160a01b031615612c47576040516326afa43560e11b815260040160405180910390fd5b60005b816060015151811015612ce75760016004600084606001518481518110612c7357612c73615e82565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060008460200151815260200190815260200160002060006101000a8154816001600160401b0302191690836001600160401b031602179055508080612cdf90615dea565b915050612c4a565b50604080516060808201835260808401516001600160601b03908116835260a0850151811660208085019182526000858701818152828901805183526006845288832097518854955192516001600160401b0316600160c01b026001600160c01b03938816600160601b026001600160c01b0319909716919097161794909417169390931790945584518084018652868601516001600160a01b03908116825281860184815294880151828801908152925184526005865295909220825181549087166001600160a01b0319918216178255935160018201805491909716941693909317909455925180519192612de692600285019290910190614e1b565b5050506080810151600a8054600090612e099084906001600160601b0316615d26565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508060a00151600a600c8282829054906101000a90046001600160601b0316612e559190615d26565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506109e381602001516008613dc990919063ffffffff16565b600f8181548110612ea157600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b031680612eea57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612f155780604051636c51fda960e11b815260040161097e9190615878565b600d54600160301b900460ff1615612f405760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b038481169116146109e3576000848152600560205260409081902060010180546001600160a01b0319166001600160a01b0386161790555184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19061285590339087906158a5565b6000818152600560205260408120548190819081906060906001600160a01b031661300057604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b03909416939183918301828280156130a357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613085575b505050505090509450945094509450945091939590929450565b6130c5613bed565b6002546001600160a01b03166130ee5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a082319061311f903090600401615878565b60206040518083038186803b15801561313757600080fd5b505afa15801561314b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061316f919061531e565b600a549091506001600160601b0316818111156131a35780826040516354ced18160e11b815260040161097e929190615902565b818110156115c85760006131b78284615d7b565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb906131ea908790859060040161588c565b602060405180830381600087803b15801561320457600080fd5b505af1158015613218573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061323c91906152e8565b61325957604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600848260405161328a92919061588c565b60405180910390a150505050565b600d54600160301b900460ff16156132c35760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b03166132f857604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c6133278385615d26565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b031661336f9190615d26565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f3f1ddc3ab1bdb39001ad76ca51a0e6f57ce6627c69f251d1de41622847721cde8234846133c29190615ce3565b6040516126c0929190615902565b6133d8613bed565b61232481613deb565b6000806133ed84613916565b60025491935091506001600160a01b03161580159061341457506001600160601b03821615155b156134c35760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906134549086906001600160601b0387169060040161588c565b602060405180830381600087803b15801561346e57600080fd5b505af1158015613482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a691906152e8565b6134c357604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613519576040519150601f19603f3d011682016040523d82523d6000602084013e61351e565b606091505b505090508061354057604051630dcf35db60e41b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b604080516060810182526000808252602082018190529181019190915260006135c88460000151612863565b6000818152600e60205260409020549091506001600160a01b03168061360457604051631dfd6e1360e21b81526004810183905260240161097e565b600082866080015160405160200161361d929190615902565b60408051601f198184030181529181528151602092830120600081815260109093529120549091508061366357604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d01519351613692978a979096959101615b02565b6040516020818303038152906040528051906020012081146136c75760405163354a450b60e21b815260040160405180910390fd5b60006136d68760000151613e8f565b90508061379d578651604051631d2827a760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e9413d389161372a9190600401615b6d565b60206040518083038186803b15801561374257600080fd5b505afa158015613756573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061377a919061531e565b90508061379d57865160405163175dadad60e01b815261097e9190600401615b6d565b60008860800151826040516020016137bf929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006137e68a83613f82565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a61138881101561382157600080fd5b61138881039050846040820482031161383957600080fd5b50823b61384557600080fd5b60008083516020850160008789f190505b9392505050565b6000811561388a576012546138839086908690600160201b900463ffffffff1686613fed565b90506138a4565b6012546138a1908690869063ffffffff1686614057565b90505b949350505050565b6000805b60135481101561390d57826001600160a01b0316601382815481106138d7576138d7615e82565b6000918252602090912001546001600160a01b031614156138fb5750600192915050565b8061390581615dea565b9150506138b0565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879687969495948601939192908301828280156139a257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613984575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613a7e576004600084604001518381518110613a2e57613a2e615e82565b6020908102919091018101516001600160a01b031682528181019290925260409081016000908120898252909252902080546001600160401b031916905580613a7681615dea565b915050613a07565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613ab66002830182614e80565b5050600085815260066020526040812055613ad2600886614144565b50600a8054859190600090613af19084906001600160601b0316615d92565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613b399190615d92565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081018690526001600160a01b03851691810191909152606081018390526001600160401b03821660808201526000908190819060a00160408051601f198184030181529082905280516020918201209250613bc9918991849101615902565b60408051808303601f19018152919052805160209091012097909650945050505050565b6000546001600160a01b03163314613c405760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b604482015260640161097e565b565b60408051602081019091526000815281613c6b5750604080516020810190915260008152610ebe565b63125fa26760e31b613c7d8385615dba565b6001600160e01b03191614613ca557604051632923fee760e11b815260040160405180910390fd5b613cb28260048186615cb9565b8101906138569190615378565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613cf891511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b60004661a4b1811480613d45575062066eed81145b15613dc25760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d8457600080fd5b505afa158015613d98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dbc919061531e565b91505090565b4391505090565b60006138568383614150565b6000610ebe825490565b6000613856838361419f565b6001600160a01b038116331415613e3e5760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b604482015260640161097e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60004661a4b1811480613ea4575062066eed81145b80613eb1575062066eee81145b15613f7357610100836001600160401b0316613ecb613d30565b613ed59190615d7b565b1180613ef15750613ee4613d30565b836001600160401b031610155b15613eff5750600092915050565b6040516315a03d4160e11b8152606490632b407a8290613f23908690600401615b6d565b60206040518083038186803b158015613f3b57600080fd5b505afa158015613f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613856919061531e565b50506001600160401b03164090565b6000613fb68360000151846020015185604001518660600151868860a001518960c001518a60e001518b61010001516141c9565b60038360200151604051602001613fce929190615a4a565b60408051601f1981840301815291905280516020909101209392505050565b600080613ff86143e4565b905060005a6140078888615ce3565b6140119190615d7b565b61401b9085615d5c565b9050600061403463ffffffff871664e8d4a51000615d5c565b9050826140418284615ce3565b61404b9190615ce3565b98975050505050505050565b600080614062614440565b905060008113614088576040516321ea67b360e11b81526004810182905260240161097e565b60006140926143e4565b9050600082825a6140a38b8b615ce3565b6140ad9190615d7b565b6140b79088615d5c565b6140c19190615ce3565b6140d390670de0b6b3a7640000615d5c565b6140dd9190615d48565b905060006140f663ffffffff881664e8d4a51000615d5c565b905061410d81676765c793fa10079d601b1b615d7b565b82111561412d5760405163e80fa38160e01b815260040160405180910390fd5b6141378183615ce3565b9998505050505050505050565b6000613856838361450b565b600081815260018301602052604081205461419757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ebe565b506000610ebe565b60008260000182815481106141b6576141b6615e82565b9060005260206000200154905092915050565b6141d2896145fe565b61421b5760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b604482015260640161097e565b614224886145fe565b6142685760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b604482015260640161097e565b614271836145fe565b6142bd5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e206375727665000000604482015260640161097e565b6142c6826145fe565b6143115760405162461bcd60e51b815260206004820152601c60248201527b73486173685769746e657373206973206e6f74206f6e20637572766560201b604482015260640161097e565b61431d878a88876146c1565b6143655760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b604482015260640161097e565b60006143718a876147d5565b90506000614384898b878b868989614839565b90506000614395838d8d8a8661494c565b9050808a146143d65760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b604482015260640161097e565b505050505050505050505050565b60004661a4b18114806143f9575062066eed81145b1561443857606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d8457600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561449e57600080fd5b505afa1580156144b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144d691906156b7565b5094509092508491505080156144fa57506144f18242615d7b565b8463ffffffff16105b156138a45750601154949350505050565b600081815260018301602052604081205480156145f457600061452f600183615d7b565b855490915060009061454390600190615d7b565b90508181146145a857600086600001828154811061456357614563615e82565b906000526020600020015490508087600001848154811061458657614586615e82565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806145b9576145b9615e6c565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610ebe565b6000915050610ebe565b80516000906401000003d0191161464c5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b604482015260640161097e565b60208201516401000003d0191161469a5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b604482015260640161097e565b60208201516401000003d0199080096146ba8360005b602002015161498c565b1492915050565b60006001600160a01b0382166147075760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b604482015260640161097e565b60208401516000906001161561471e57601c614721565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe199182039250600091908909875160408051600080825260209091019182905292935060019161478b91869188918790615910565b6020604051602081039080840390855afa1580156147ad573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b6147dd614e9e565b61480a600184846040516020016147f693929190615857565b6040516020818303038152906040526149b0565b90505b614816816145fe565b610ebe57805160408051602081019290925261483291016147f6565b905061480d565b614841614e9e565b825186516401000003d01990819006910614156148a05760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e63740000604482015260640161097e565b6148ab8789886149fe565b6148f05760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b604482015260640161097e565b6148fb8486856149fe565b6149415760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b604482015260640161097e565b61404b868484614b19565b60006002868686858760405160200161496a969594939291906157fd565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b6149b8614e9e565b6149c182614bdc565b81526149d66149d18260006146b0565b614c17565b602082018190526002900660011415611dc8576020810180516401000003d019039052919050565b600082614a3b5760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b604482015260640161097e565b83516020850151600090614a5190600290615e2c565b15614a5d57601c614a60565b601b5b9050600070014551231950b75fc4402da1732fc9bebe19838709604080516000808252602090910191829052919250600190614aa3908390869088908790615910565b6020604051602081039080840390855afa158015614ac5573d6000803e3d6000fd5b505050602060405103519050600086604051602001614ae491906157eb565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614b21614e9e565b835160208086015185519186015160009384938493614b4293909190614c37565b919450925090506401000003d019858209600114614b9e5760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b604482015260640161097e565b60405180604001604052806401000003d01980614bbd57614bbd615e56565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611dc857604080516020808201939093528151808203840181529082019091528051910120614be4565b6000610ebe826002614c306401000003d0196001615ce3565b901c614d17565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614c7783838585614dae565b9098509050614c8888828e88614dd2565b9098509050614c9988828c87614dd2565b90985090506000614cac8d878b85614dd2565b9098509050614cbd88828686614dae565b9098509050614cce88828e89614dd2565b9098509050818114614d03576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614d07565b8196505b5050505050509450945094915050565b600080614d22614ebc565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614d54614eda565b60208160c0846005600019fa925082614da45760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b604482015260640161097e565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614e70579160200282015b82811115614e7057825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614e3b565b50614e7c929150614ef8565b5090565b50805460008255906000526020600020908101906123249190614ef8565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614e7c5760008155600101614ef9565b8035611dc881615eae565b600082601f830112614f2957600080fd5b813560206001600160401b03821115614f4457614f44615e98565b8160051b614f53828201615c89565b838152828101908684018388018501891015614f6e57600080fd5b600093505b85841015614f9a578035614f8681615eae565b835260019390930192918401918401614f73565b50979650505050505050565b600082601f830112614fb757600080fd5b614fbf615c1c565b808385604086011115614fd157600080fd5b60005b6002811015614ff3578135845260209384019390910190600101614fd4565b509095945050505050565b60008083601f84011261501057600080fd5b5081356001600160401b0381111561502757600080fd5b60208301915083602082850101111561503f57600080fd5b9250929050565b600082601f83011261505757600080fd5b81356001600160401b0381111561507057615070615e98565b615083601f8201601f1916602001615c89565b81815284602083860101111561509857600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156150c757600080fd5b6150cf615c44565b905081356001600160401b0380821682146150e957600080fd5b8183526020840135602084015261510260408501615168565b604084015261511360608501615168565b606084015261512460808501614f0d565b608084015260a084013591508082111561513d57600080fd5b5061514a84828501615046565b60a08301525092915050565b803561ffff81168114611dc857600080fd5b803563ffffffff81168114611dc857600080fd5b80516001600160501b0381168114611dc857600080fd5b80356001600160601b0381168114611dc857600080fd5b6000602082840312156151bc57600080fd5b813561385681615eae565b600080604083850312156151da57600080fd5b82356151e581615eae565b91506151f360208401615193565b90509250929050565b6000806040838503121561520f57600080fd5b823561521a81615eae565b9150602083013561522a81615eae565b809150509250929050565b6000806060838503121561524857600080fd5b823561525381615eae565b91506060830184101561526557600080fd5b50926020919091019150565b6000806000806060858703121561528757600080fd5b843561529281615eae565b93506020850135925060408501356001600160401b038111156152b457600080fd5b6152c087828801614ffe565b95989497509550505050565b6000604082840312156152de57600080fd5b6138568383614fa6565b6000602082840312156152fa57600080fd5b815161385681615ec3565b60006020828403121561531757600080fd5b5035919050565b60006020828403121561533057600080fd5b5051919050565b6000806020838503121561534a57600080fd5b82356001600160401b0381111561536057600080fd5b61536c85828601614ffe565b90969095509350505050565b60006020828403121561538a57600080fd5b604051602081016001600160401b03811182821017156153ac576153ac615e98565b60405282356153ba81615ec3565b81529392505050565b6000808284036101c08112156153d857600080fd5b6101a0808212156153e857600080fd5b6153f0615c66565b91506153fc8686614fa6565b825261540b8660408701614fa6565b60208301526080850135604083015260a0850135606083015260c0850135608083015261543a60e08601614f0d565b60a083015261010061544e87828801614fa6565b60c0840152615461876101408801614fa6565b60e0840152610180860135908301529092508301356001600160401b0381111561548a57600080fd5b615496858286016150b5565b9150509250929050565b6000602082840312156154b257600080fd5b81356001600160401b038111156154c857600080fd5b820160c0818503121561385657600080fd5b6000602082840312156154ec57600080fd5b81356001600160401b038082111561550357600080fd5b9083019060c0828603121561551757600080fd5b61551f615c44565b823560ff8116811461553057600080fd5b81526020838101359082015261554860408401614f0d565b604082015260608301358281111561555f57600080fd5b61556b87828601614f18565b60608301525061557d60808401615193565b608082015261558e60a08401615193565b60a082015295945050505050565b6000602082840312156155ae57600080fd5b61385682615156565b60008060008060008086880360e08112156155d157600080fd5b6155da88615156565b96506155e860208901615168565b95506155f660408901615168565b945061560460608901615168565b9350608088013592506040609f198201121561561f57600080fd5b50615628615c1c565b61563460a08901615168565b815261564260c08901615168565b6020820152809150509295509295509295565b6000806040838503121561566857600080fd5b82359150602083013561522a81615eae565b6000806040838503121561568d57600080fd5b50508035926020909101359150565b6000602082840312156156ae57600080fd5b61385682615168565b600080600080600060a086880312156156cf57600080fd5b6156d88661517c565b94506020860151935060408601519250606086015191506156fb6080870161517c565b90509295509295909350565b600081518084526020808501945080840160005b838110156157405781516001600160a01b03168752958201959082019060010161571b565b509495945050505050565b8060005b60028110156109e357815184526020938401939091019060010161574f565b600081518084526020808501945080840160005b8381101561574057815187529582019590820190600101615782565b6000815180845260005b818110156157c4576020818501810151868301820152016157a8565b818111156157d6576000602083870101525b50601f01601f19169290920160200192915050565b6157f5818361574b565b604001919050565b86815261580d602082018761574b565b61581a606082018661574b565b61582760a082018561574b565b61583460e082018461574b565b60609190911b6001600160601b0319166101208201526101340195945050505050565b838152615867602082018461574b565b606081019190915260800192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b60408101610ebe828461574b565b602081526000613856602083018461576e565b918252602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b602081526000613856602083018461579e565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261598660e0840182615707565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b61ffff93841681529183166020830152909116604082015260600190565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615a2557845183529383019391830191600101615a09565b509098975050505050505050565b9182526001600160a01b0316602082015260400190565b82815260608101613856602083018461574b565b8281526040602082015260006138a4604083018461576e565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261404b60c083018461579e565b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c082018190526000906141379083018461579e565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c082018190526000906141379083018461579e565b63ffffffff92831681529116602082015260400190565b6001600160401b0391909116815260200190565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a060808201819052600090615bcb90830184615707565b979650505050505050565b6000808335601e19843603018112615bed57600080fd5b8301803591506001600160401b03821115615c0757600080fd5b60200191503681900382131561503f57600080fd5b604080519081016001600160401b0381118282101715615c3e57615c3e615e98565b60405290565b60405160c081016001600160401b0381118282101715615c3e57615c3e615e98565b60405161012081016001600160401b0381118282101715615c3e57615c3e615e98565b604051601f8201601f191681016001600160401b0381118282101715615cb157615cb1615e98565b604052919050565b60008085851115615cc957600080fd5b83861115615cd657600080fd5b5050820193919092039150565b60008219821115615cf657615cf6615e40565b500190565b60006001600160401b03828116848216808303821115615d1d57615d1d615e40565b01949350505050565b60006001600160601b03828116848216808303821115615d1d57615d1d615e40565b600082615d5757615d57615e56565b500490565b6000816000190483118215151615615d7657615d76615e40565b500290565b600082821015615d8d57615d8d615e40565b500390565b60006001600160601b0383811690831681811015615db257615db2615e40565b039392505050565b6001600160e01b03198135818116916004851015615de25780818660040360031b1b83161692505b505092915050565b6000600019821415615dfe57615dfe615e40565b5060010190565b60006001600160401b0382811680821415615e2257615e22615e40565b6001019392505050565b600082615e3b57615e3b615e56565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461232457600080fd5b801515811461232457600080fdfea164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[{\"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\":\"uint256\",\"name\":\"transferredValue\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"expectedValue\",\"type\":\"uint96\"}],\"name\":\"InvalidNativeBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"expectedVersion\",\"type\":\"uint8\"}],\"name\":\"InvalidVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIDCollisionFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"}],\"indexed\":false,\"internalType\":\"structVRFCoordinatorV2PlusUpgradedVersion.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"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\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2PlusUpgradedVersion.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"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\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"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\":\"oracleWithdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"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\":\"fulfillmentFlatFeeNativePPM\",\"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_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"}],\"internalType\":\"structVRFCoordinatorV2PlusUpgradedVersion.FeeConfig\",\"name\":\"feeConfig\",\"type\":\"tuple\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b50604051620060b4380380620060b4833981016040819052620000349162000183565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d7565b50505060601b6001600160601b031916608052620001b5565b6001600160a01b038116331415620001325760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019657600080fd5b81516001600160a01b0381168114620001ae57600080fd5b9392505050565b60805160601c615ed9620001db600039600081816104eb01526136f60152615ed96000f3fe6080604052600436106102015760003560e01c806201229114610206578063043bd6ae14610233578063088070f5146102575780630ae09540146102d757806315c48b84146102f957806318e3dd27146103215780631b6b6d2314610360578063294926571461038d578063294daa49146103ad578063330987b3146103c9578063405b84fa146103e957806340d6bb821461040957806341af6c87146104345780635d06b4ab1461046457806364d51a2a14610484578063659827441461049957806366316d8d146104b9578063689c4517146104d95780636b6feccc1461050d5780636f64f03f1461054357806372e9d5651461056357806379ba5097146105835780638402595e1461059857806386fe91c7146105b85780638da5cb5b146105d857806395b55cfc146105f65780639b1c385e146106095780639d40a6fd14610629578063a21a23e414610656578063a4c0ed361461066b578063aa433aff1461068b578063aefb212f146106ab578063b08c8795146106d8578063b2a7cac5146106f8578063bec4c08c14610718578063caf70c4a14610738578063cb63179714610758578063ce3f471914610778578063d98e620e1461078b578063da2f2610146107ab578063dac83d29146107e1578063dc311dd314610801578063e72f6e3014610832578063ee9d2d3814610852578063f2fde38b1461087f575b600080fd5b34801561021257600080fd5b5061021b61089f565b60405161022a939291906159cf565b60405180910390f35b34801561023f57600080fd5b5061024960115481565b60405190815260200161022a565b34801561026357600080fd5b50600d5461029f9061ffff81169063ffffffff62010000820481169160ff600160301b82041691600160381b8204811691600160581b90041685565b6040805161ffff909616865263ffffffff9485166020870152921515928501929092528216606084015216608082015260a00161022a565b3480156102e357600080fd5b506102f76102f2366004615650565b61091b565b005b34801561030557600080fd5b5061030e60c881565b60405161ffff909116815260200161022a565b34801561032d57600080fd5b50600a5461034890600160601b90046001600160601b031681565b6040516001600160601b03909116815260200161022a565b34801561036c57600080fd5b50600254610380906001600160a01b031681565b60405161022a9190615873565b34801561039957600080fd5b506102f76103a83660046151c2565b6109e9565b3480156103b957600080fd5b506040516001815260200161022a565b3480156103d557600080fd5b506103486103e43660046153be565b610b66565b3480156103f557600080fd5b506102f7610404366004615650565b611041565b34801561041557600080fd5b5061041f6101f481565b60405163ffffffff909116815260200161022a565b34801561044057600080fd5b5061045461044f366004615300565b61142c565b604051901515815260200161022a565b34801561047057600080fd5b506102f761047f3660046151a5565b6115cd565b34801561049057600080fd5b5061030e606481565b3480156104a557600080fd5b506102f76104b43660046151f7565b611684565b3480156104c557600080fd5b506102f76104d43660046151c2565b6116e4565b3480156104e557600080fd5b506103807f000000000000000000000000000000000000000000000000000000000000000081565b34801561051957600080fd5b506012546105359063ffffffff80821691600160201b90041682565b60405161022a929190615b51565b34801561054f57600080fd5b506102f761055e366004615230565b6118ac565b34801561056f57600080fd5b50600354610380906001600160a01b031681565b34801561058f57600080fd5b506102f76119b3565b3480156105a457600080fd5b506102f76105b33660046151a5565b611a5d565b3480156105c457600080fd5b50600a54610348906001600160601b031681565b3480156105e457600080fd5b506000546001600160a01b0316610380565b6102f7610604366004615300565b611b69565b34801561061557600080fd5b5061024961062436600461549b565b611cad565b34801561063557600080fd5b50600754610649906001600160401b031681565b60405161022a9190615b68565b34801561066257600080fd5b5061024961201d565b34801561067757600080fd5b506102f761068636600461526c565b61226b565b34801561069757600080fd5b506102f76106a6366004615300565b612408565b3480156106b757600080fd5b506106cb6106c6366004615675565b61246b565b60405161022a91906158ea565b3480156106e457600080fd5b506102f76106f33660046155b2565b61256c565b34801561070457600080fd5b506102f7610713366004615300565b6126e0565b34801561072457600080fd5b506102f7610733366004615650565b612804565b34801561074457600080fd5b506102496107533660046152c7565b61299b565b34801561076457600080fd5b506102f7610773366004615650565b6129cb565b6102f7610786366004615332565b612cb8565b34801561079757600080fd5b506102496107a6366004615300565b612fc9565b3480156107b757600080fd5b506103806107c6366004615300565b600e602052600090815260409020546001600160a01b031681565b3480156107ed57600080fd5b506102f76107fc366004615650565b612fea565b34801561080d57600080fd5b5061082161081c366004615300565b6130fa565b60405161022a959493929190615b7c565b34801561083e57600080fd5b506102f761084d3660046151a5565b6131f5565b34801561085e57600080fd5b5061024961086d366004615300565b60106020526000908152604090205481565b34801561088b57600080fd5b506102f761089a3660046151a5565b6133d0565b600d54600f805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff1693919283919083018282801561090957602002820191906000526020600020905b8154815260200190600101908083116108f5575b50505050509050925092509250909192565b60008281526005602052604090205482906001600160a01b03168061095357604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146109875780604051636c51fda960e11b815260040161097e9190615873565b60405180910390fd5b600d54600160301b900460ff16156109b25760405163769dd35360e11b815260040160405180910390fd5b6109bb8461142c565b156109d957604051631685ecdd60e31b815260040160405180910390fd5b6109e384846133e1565b50505050565b600d54600160301b900460ff1615610a145760405163769dd35360e11b815260040160405180910390fd5b336000908152600c60205260409020546001600160601b0380831691161015610a5057604051631e9acf1760e31b815260040160405180910390fd5b336000908152600c602052604081208054839290610a789084906001600160601b0316615d8d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610ac09190615d8d565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610b3a576040519150601f19603f3d011682016040523d82523d6000602084013e610b3f565b606091505b5050905080610b615760405163950b247960e01b815260040160405180910390fd5b505050565b600d54600090600160301b900460ff1615610b945760405163769dd35360e11b815260040160405180910390fd5b60005a90506000610ba5858561359c565b90506000846060015163ffffffff166001600160401b03811115610bcb57610bcb615e93565b604051908082528060200260200182016040528015610bf4578160200160208202803683370190505b50905060005b856060015163ffffffff16811015610c6b57826040015181604051602001610c239291906158fd565b6040516020818303038152906040528051906020012060001c828281518110610c4e57610c4e615e7d565b602090810291909101015280610c6381615de5565b915050610bfa565b5060208083018051600090815260109092526040808320839055905190518291631fe543e360e01b91610ca391908690602401615a59565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600d805460ff60301b1916600160301b179055908801516080890151919250600091610d089163ffffffff16908461380f565b600d805460ff60301b19169055602089810151600090815260069091526040902054909150600160c01b90046001600160401b0316610d48816001615cf6565b6020808b0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08a01518051610d9590600190615d76565b81518110610da557610da5615e7d565b602091010151600d5460f89190911c6001149150600090610dd6908a90600160581b900463ffffffff163a8561385d565b90508115610edf576020808c01516000908152600690915260409020546001600160601b03808316600160601b909204161015610e2657604051631e9acf1760e31b815260040160405180910390fd5b60208b81015160009081526006909152604090208054829190600c90610e5d908490600160601b90046001600160601b0316615d8d565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600c909152812080548594509092610eb691859116615d21565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610fcb565b6020808c01516000908152600690915260409020546001600160601b0380831691161015610f2057604051631e9acf1760e31b815260040160405180910390fd5b6020808c015160009081526006909152604081208054839290610f4d9084906001600160601b0316615d8d565b82546101009290920a6001600160601b0381810219909316918316021790915589516000908152600e60209081526040808320546001600160a01b03168352600b909152812080548594509092610fa691859116615d21565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8a6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051611028939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b92915050565b600d54600160301b900460ff161561106c5760405163769dd35360e11b815260040160405180910390fd5b611075816138ac565b6110945780604051635428d44960e01b815260040161097e9190615873565b6000806000806110a3866130fa565b945094505093509350336001600160a01b0316826001600160a01b0316146111065760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b604482015260640161097e565b61110f8661142c565b156111555760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b604482015260640161097e565b60006040518060c0016040528061116a600190565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b031681525090506000816040516020016111be919061593c565b60405160208183030381529060405290506111d888613916565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b03881690611211908590600401615929565b6000604051808303818588803b15801561122a57600080fd5b505af115801561123e573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150611267905057506001600160601b03861615155b156113315760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061129e908a908a906004016158ba565b602060405180830381600087803b1580156112b857600080fd5b505af11580156112cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f091906152e3565b6113315760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b604482015260640161097e565b600d805460ff60301b1916600160301b17905560005b83518110156113da5783818151811061136257611362615e7d565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b81526004016113959190615873565b600060405180830381600087803b1580156113af57600080fd5b505af11580156113c3573d6000803e3d6000fd5b5050505080806113d290615de5565b915050611347565b50600d805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be41879061141a9089908b90615887565b60405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b03908116825260018301541681850152600282018054845181870281018701865281815287969395860193909291908301828280156114b657602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611498575b505050505081525050905060005b8160400151518110156115c35760005b600f548110156115b0576000611579600f83815481106114f6576114f6615e7d565b90600052602060002001548560400151858151811061151757611517615e7d565b602002602001015188600460008960400151898151811061153a5761153a615e7d565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208d82529092529020546001600160401b0316613b64565b506000818152601060205260409020549091501561159d5750600195945050505050565b50806115a881615de5565b9150506114d4565b50806115bb81615de5565b9150506114c4565b5060009392505050565b6115d5613bed565b6115de816138ac565b156115fe578060405163ac8a27ef60e01b815260040161097e9190615873565b601380546001810182556000919091527f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af0162590611679908390615873565b60405180910390a150565b61168c613bed565b6002546001600160a01b0316156116b657604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b600d54600160301b900460ff161561170f5760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b03166117385760405163c1f0c0a160e01b815260040160405180910390fd5b336000908152600b60205260409020546001600160601b038083169116101561177457604051631e9acf1760e31b815260040160405180910390fd5b336000908152600b60205260408120805483929061179c9084906001600160601b0316615d8d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166117e49190615d8d565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061183990859085906004016158ba565b602060405180830381600087803b15801561185357600080fd5b505af1158015611867573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061188b91906152e3565b6118a857604051631e9acf1760e31b815260040160405180910390fd5b5050565b6118b4613bed565b6040805180820182526000916118e391908490600290839083908082843760009201919091525061299b915050565b6000818152600e60205260409020549091506001600160a01b03161561191f57604051634a0b8fa760e01b81526004810182905260240161097e565b6000818152600e6020908152604080832080546001600160a01b0319166001600160a01b038816908117909155600f805460018101825594527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802909301849055518381527fe729ae16526293f74ade739043022254f1489f616295a25bf72dfb4511ed73b8910160405180910390a2505050565b6001546001600160a01b03163314611a065760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b604482015260640161097e565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b611a65613bed565b600a544790600160601b90046001600160601b031681811115611a9f5780826040516354ced18160e11b815260040161097e9291906158fd565b81811015610b61576000611ab38284615d76565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d8060008114611b02576040519150601f19603f3d011682016040523d82523d6000602084013e611b07565b606091505b5050905080611b295760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c8583604051611b5a929190615887565b60405180910390a15050505050565b600d54600160301b900460ff1615611b945760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b0316611bc957604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611bf88385615d21565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611c409190615d21565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611c939190615cde565b604051611ca19291906158fd565b60405180910390a25050565b600d54600090600160301b900460ff1615611cdb5760405163769dd35360e11b815260040160405180910390fd5b6020808301356000908152600590915260409020546001600160a01b0316611d1657604051630fb532db60e11b815260040160405180910390fd5b3360009081526004602090815260408083208583013584529091529020546001600160401b031680611d63578260200135336040516379bfd40160e01b815260040161097e929190615a2e565b600d5461ffff16611d7a6060850160408601615597565b61ffff161080611d9d575060c8611d976060850160408601615597565b61ffff16115b15611dd757611db26060840160408501615597565b600d5460405163539c34bb60e11b815261097e929161ffff169060c8906004016159b1565b600d5462010000900463ffffffff16611df66080850160608601615697565b63ffffffff161115611e3c57611e126080840160608501615697565b600d54604051637aebf00f60e11b815261097e929162010000900463ffffffff1690600401615b51565b6101f4611e4f60a0850160808601615697565b63ffffffff161115611e8957611e6b60a0840160808501615697565b6101f46040516311ce1afb60e21b815260040161097e929190615b51565b6000611e96826001615cf6565b9050600080611eac863533602089013586613b64565b90925090506000611ec8611ec360a0890189615bd1565b613c42565b90506000611ed582613cbf565b905083611ee0613d30565b60208a0135611ef560808c0160608d01615697565b611f0560a08d0160808e01615697565b3386604051602001611f1d9796959493929190615ab1565b604051602081830303815290604052805190602001206010600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190611f949190615597565b8e6060016020810190611fa79190615697565b8f6080016020810190611fba9190615697565b89604051611fcd96959493929190615a72565b60405180910390a45050336000908152600460209081526040808320898301358452909152902080546001600160401b0319166001600160401b039490941693909317909255925050505b919050565b600d54600090600160301b900460ff161561204b5760405163769dd35360e11b815260040160405180910390fd5b600033612059600143615d76565b600754604051606093841b6001600160601b03199081166020830152924060348201523090931b909116605483015260c01b6001600160c01b031916606882015260700160408051601f198184030181529190528051602090910120600780549192506001600160401b039091169060006120d383615e00565b91906101000a8154816001600160401b0302191690836001600160401b03160217905550506000806001600160401b0381111561211257612112615e93565b60405190808252806020026020018201604052801561213b578160200160208202803683370190505b506040805160608082018352600080835260208084018281528486018381528984526006835286842095518654925191516001600160601b039182166001600160c01b031990941693909317600160601b9190921602176001600160c01b0316600160c01b6001600160401b039092169190910217909355835191820184523382528183018181528285018681528883526005855294909120825181546001600160a01b03199081166001600160a01b03928316178355925160018301805490941691161790915592518051949550909361221c9260028501920190614e16565b5061222c91506008905083613dc0565b50817f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d3360405161225d9190615873565b60405180910390a250905090565b600d54600160301b900460ff16156122965760405163769dd35360e11b815260040160405180910390fd5b6002546001600160a01b031633146122c1576040516344b0e3c360e01b815260040160405180910390fd5b602081146122e257604051638129bbcd60e01b815260040160405180910390fd5b60006122f082840184615300565b6000818152600560205260409020549091506001600160a01b031661232857604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061234f8385615d21565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b03166123979190615d21565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846123ea9190615cde565b6040516123f89291906158fd565b60405180910390a2505050505050565b612410613bed565b6000818152600560205260409020546001600160a01b031661244557604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020546124689082906001600160a01b03166133e1565b50565b606060006124796008613dcc565b905080841061249b57604051631390f2a160e01b815260040160405180910390fd5b60006124a78486615cde565b9050818111806124b5575083155b6124bf57806124c1565b815b905060006124cf8683615d76565b6001600160401b038111156124e6576124e6615e93565b60405190808252806020026020018201604052801561250f578160200160208202803683370190505b50905060005b81518110156125625761253361252b8883615cde565b600890613dd6565b82828151811061254557612545615e7d565b60209081029190910101528061255a81615de5565b915050612515565b5095945050505050565b612574613bed565b60c861ffff871611156125a157858660c860405163539c34bb60e11b815260040161097e939291906159b1565b600082136125c5576040516321ea67b360e11b81526004810183905260240161097e565b6040805160a0808201835261ffff891680835263ffffffff89811660208086018290526000868801528a831660608088018290528b85166080988901819052600d805465ffffffffffff1916881762010000870217600160301b600160781b031916600160381b850263ffffffff60581b191617600160581b83021790558a51601280548d8701519289166001600160401b031990911617600160201b92891692909202919091179081905560118d90558a519788528785019590955298860191909152840196909652938201879052838116928201929092529190921c90911660c08201527f777357bb93f63d088f18112d3dba38457aec633eb8f1341e1d418380ad328e789060e00160405180910390a1505050505050565b600d54600160301b900460ff161561270b5760405163769dd35360e11b815260040160405180910390fd5b6000818152600560205260409020546001600160a01b031661274057604051630fb532db60e11b815260040160405180910390fd5b6000818152600560205260409020600101546001600160a01b03163314612797576000818152600560205260409081902060010154905163d084e97560e01b815261097e916001600160a01b031690600401615873565b6000818152600560205260409081902080546001600160a01b031980821633908117845560019093018054909116905591516001600160a01b039092169183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611ca19185916158a0565b60008281526005602052604090205482906001600160a01b03168061283c57604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146128675780604051636c51fda960e11b815260040161097e9190615873565b600d54600160301b900460ff16156128925760405163769dd35360e11b815260040160405180910390fd5b600084815260056020526040902060020154606414156128c5576040516305a48e0f60e01b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316156128fc576109e3565b6001600160a01b0383166000818152600460209081526040808320888452825280832080546001600160401b031916600190811790915560058352818420600201805491820181558452919092200180546001600160a01b0319169092179091555184907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e19061298d908690615873565b60405180910390a250505050565b6000816040516020016129ae91906158dc565b604051602081830303815290604052805190602001209050919050565b60008281526005602052604090205482906001600160a01b031680612a0357604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b03821614612a2e5780604051636c51fda960e11b815260040161097e9190615873565b600d54600160301b900460ff1615612a595760405163769dd35360e11b815260040160405180910390fd5b612a628461142c565b15612a8057604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b03831660009081526004602090815260408083208784529091529020546001600160401b0316612ace5783836040516379bfd40160e01b815260040161097e929190615a2e565b600084815260056020908152604080832060020180548251818502810185019093528083529192909190830182828015612b3157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612b13575b50505050509050600060018251612b489190615d76565b905060005b8251811015612c5457856001600160a01b0316838281518110612b7257612b72615e7d565b60200260200101516001600160a01b03161415612c42576000838381518110612b9d57612b9d615e7d565b6020026020010151905080600560008a81526020019081526020016000206002018381548110612bcf57612bcf615e7d565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255898152600590915260409020600201805480612c1a57612c1a615e67565b600082815260209020810160001990810180546001600160a01b031916905501905550612c54565b80612c4c81615de5565b915050612b4d565b506001600160a01b03851660009081526004602090815260408083208984529091529081902080546001600160401b03191690555186907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7906123f8908890615873565b6000612cc6828401846154d5565b9050806000015160ff16600114612cff57805160405163237d181f60e21b815260ff90911660048201526001602482015260440161097e565b8060a001516001600160601b03163414612d435760a08101516040516306acf13560e41b81523460048201526001600160601b03909116602482015260440161097e565b6020808201516000908152600590915260409020546001600160a01b031615612d7f576040516326afa43560e11b815260040160405180910390fd5b60005b816060015151811015612e1f5760016004600084606001518481518110612dab57612dab615e7d565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060008460200151815260200190815260200160002060006101000a8154816001600160401b0302191690836001600160401b031602179055508080612e1790615de5565b915050612d82565b50604080516060808201835260808401516001600160601b03908116835260a0850151811660208085019182526000858701818152828901805183526006845288832097518854955192516001600160401b0316600160c01b026001600160c01b03938816600160601b026001600160c01b0319909716919097161794909417169390931790945584518084018652868601516001600160a01b03908116825281860184815294880151828801908152925184526005865295909220825181549087166001600160a01b0319918216178255935160018201805491909716941693909317909455925180519192612f1e92600285019290910190614e16565b5050506080810151600a8054600090612f419084906001600160601b0316615d21565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508060a00151600a600c8282829054906101000a90046001600160601b0316612f8d9190615d21565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506109e381602001516008613dc090919063ffffffff16565b600f8181548110612fd957600080fd5b600091825260209091200154905081565b60008281526005602052604090205482906001600160a01b03168061302257604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b0382161461304d5780604051636c51fda960e11b815260040161097e9190615873565b600d54600160301b900460ff16156130785760405163769dd35360e11b815260040160405180910390fd5b6000848152600560205260409020600101546001600160a01b038481169116146109e3576000848152600560205260409081902060010180546001600160a01b0319166001600160a01b0386161790555184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a19061298d90339087906158a0565b6000818152600560205260408120548190819081906060906001600160a01b031661313857604051630fb532db60e11b815260040160405180910390fd5b60008681526006602090815260408083205460058352928190208054600290910180548351818602810186019094528084526001600160601b0380871696600160601b810490911695600160c01b9091046001600160401b0316946001600160a01b03909416939183918301828280156131db57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116131bd575b505050505090509450945094509450945091939590929450565b6131fd613bed565b6002546001600160a01b03166132265760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190613257903090600401615873565b60206040518083038186803b15801561326f57600080fd5b505afa158015613283573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132a79190615319565b600a549091506001600160601b0316818111156132db5780826040516354ced18160e11b815260040161097e9291906158fd565b81811015610b615760006132ef8284615d76565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb906133229087908590600401615887565b602060405180830381600087803b15801561333c57600080fd5b505af1158015613350573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061337491906152e3565b61339157604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b43660084826040516133c2929190615887565b60405180910390a150505050565b6133d8613bed565b61246881613de2565b6000806133ed84613916565b60025491935091506001600160a01b03161580159061341457506001600160601b03821615155b156134c35760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb906134549086906001600160601b03871690600401615887565b602060405180830381600087803b15801561346e57600080fd5b505af1158015613482573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a691906152e3565b6134c357604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613519576040519150601f19603f3d011682016040523d82523d6000602084013e61351e565b606091505b50509050806135405760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b038581166020830152841681830152905186917f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4919081900360600190a25050505050565b604080516060810182526000808252602082018190529181019190915260006135c8846000015161299b565b6000818152600e60205260409020549091506001600160a01b03168061360457604051631dfd6e1360e21b81526004810183905260240161097e565b600082866080015160405160200161361d9291906158fd565b60408051601f198184030181529181528151602092830120600081815260109093529120549091508061366357604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d01519351613692978a979096959101615afd565b6040516020818303038152906040528051906020012081146136c75760405163354a450b60e21b815260040160405180910390fd5b60006136d68760000151613e86565b90508061379d578651604051631d2827a760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e9413d389161372a9190600401615b68565b60206040518083038186803b15801561374257600080fd5b505afa158015613756573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061377a9190615319565b90508061379d57865160405163175dadad60e01b815261097e9190600401615b68565b60008860800151826040516020016137bf929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006137e68a83613f63565b604080516060810182529889526020890196909652948701949094525093979650505050505050565b60005a61138881101561382157600080fd5b61138881039050846040820482031161383957600080fd5b50823b61384557600080fd5b60008083516020850160008789f190505b9392505050565b6000811561388a576012546138839086908690600160201b900463ffffffff1686613fce565b90506138a4565b6012546138a1908690869063ffffffff1686614038565b90505b949350505050565b6000805b60135481101561390d57826001600160a01b0316601382815481106138d7576138d7615e7d565b6000918252602090912001546001600160a01b031614156138fb5750600192915050565b8061390581615de5565b9150506138b0565b50600092915050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879687969495948601939192908301828280156139a257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311613984575b505050919092525050506000858152600660209081526040808320815160608101835290546001600160601b03808216808452600160601b8304909116948301859052600160c01b9091046001600160401b0316928201929092529096509094509192505b826040015151811015613a7e576004600084604001518381518110613a2e57613a2e615e7d565b6020908102919091018101516001600160a01b031682528181019290925260409081016000908120898252909252902080546001600160401b031916905580613a7681615de5565b915050613a07565b50600085815260056020526040812080546001600160a01b03199081168255600182018054909116905590613ab66002830182614e7b565b5050600085815260066020526040812055613ad2600886614125565b50600a8054859190600090613af19084906001600160601b0316615d8d565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555082600a600c8282829054906101000a90046001600160601b0316613b399190615d8d565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050915091565b60408051602081018690526001600160a01b03851691810191909152606081018390526001600160401b03821660808201526000908190819060a00160408051601f198184030181529082905280516020918201209250613bc99189918491016158fd565b60408051808303601f19018152919052805160209091012097909650945050505050565b6000546001600160a01b03163314613c405760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b604482015260640161097e565b565b60408051602081019091526000815281613c6b575060408051602081019091526000815261103b565b63125fa26760e31b613c7d8385615db5565b6001600160e01b03191614613ca557604051632923fee760e11b815260040160405180910390fd5b613cb28260048186615cb4565b8101906138569190615373565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613cf891511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b600046613d3c81614131565b15613db95760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d7b57600080fd5b505afa158015613d8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613db39190615319565b91505090565b4391505090565b60006138568383614154565b600061103b825490565b600061385683836141a3565b6001600160a01b038116331415613e355760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b604482015260640161097e565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613e9281614131565b15613f5457610100836001600160401b0316613eac613d30565b613eb69190615d76565b1180613ed25750613ec5613d30565b836001600160401b031610155b15613ee05750600092915050565b6040516315a03d4160e11b8152606490632b407a8290613f04908690600401615b68565b60206040518083038186803b158015613f1c57600080fd5b505afa158015613f30573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138569190615319565b50506001600160401b03164090565b6000613f978360000151846020015185604001518660600151868860a001518960c001518a60e001518b61010001516141cd565b60038360200151604051602001613faf929190615a45565b60408051601f1981840301815291905280516020909101209392505050565b600080613fd96143e8565b905060005a613fe88888615cde565b613ff29190615d76565b613ffc9085615d57565b9050600061401563ffffffff871664e8d4a51000615d57565b9050826140228284615cde565b61402c9190615cde565b98975050505050505050565b60008061404361443b565b905060008113614069576040516321ea67b360e11b81526004810182905260240161097e565b60006140736143e8565b9050600082825a6140848b8b615cde565b61408e9190615d76565b6140989088615d57565b6140a29190615cde565b6140b490670de0b6b3a7640000615d57565b6140be9190615d43565b905060006140d763ffffffff881664e8d4a51000615d57565b90506140ee81676765c793fa10079d601b1b615d76565b82111561410e5760405163e80fa38160e01b815260040160405180910390fd5b6141188183615cde565b9998505050505050505050565b60006138568383614506565b600061a4b1821480614145575062066eed82145b8061103b57505062066eee1490565b600081815260018301602052604081205461419b5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561103b565b50600061103b565b60008260000182815481106141ba576141ba615e7d565b9060005260206000200154905092915050565b6141d6896145f9565b61421f5760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b604482015260640161097e565b614228886145f9565b61426c5760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b604482015260640161097e565b614275836145f9565b6142c15760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e206375727665000000604482015260640161097e565b6142ca826145f9565b6143155760405162461bcd60e51b815260206004820152601c60248201527b73486173685769746e657373206973206e6f74206f6e20637572766560201b604482015260640161097e565b614321878a88876146bc565b6143695760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b604482015260640161097e565b60006143758a876147d0565b90506000614388898b878b868989614834565b90506000614399838d8d8a86614947565b9050808a146143da5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b604482015260640161097e565b505050505050505050505050565b6000466143f481614131565b1561443357606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b815260040160206040518083038186803b158015613d7b57600080fd5b600091505090565b600d5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a0929190829003018186803b15801561449957600080fd5b505afa1580156144ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144d191906156b2565b5094509092508491505080156144f557506144ec8242615d76565b8463ffffffff16105b156138a45750601154949350505050565b600081815260018301602052604081205480156145ef57600061452a600183615d76565b855490915060009061453e90600190615d76565b90508181146145a357600086600001828154811061455e5761455e615e7d565b906000526020600020015490508087600001848154811061458157614581615e7d565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806145b4576145b4615e67565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061103b565b600091505061103b565b80516000906401000003d019116146475760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b604482015260640161097e565b60208201516401000003d019116146955760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b604482015260640161097e565b60208201516401000003d0199080096146b58360005b6020020151614987565b1492915050565b60006001600160a01b0382166147025760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b604482015260640161097e565b60208401516000906001161561471957601c61471c565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020909101918290529293506001916147869186918891879061590b565b6020604051602081039080840390855afa1580156147a8573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b6147d8614e99565b614805600184846040516020016147f193929190615852565b6040516020818303038152906040526149ab565b90505b614811816145f9565b61103b57805160408051602081019290925261482d91016147f1565b9050614808565b61483c614e99565b825186516401000003d019908190069106141561489b5760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e63740000604482015260640161097e565b6148a68789886149f9565b6148eb5760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b604482015260640161097e565b6148f68486856149f9565b61493c5760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b604482015260640161097e565b61402c868484614b14565b600060028686868587604051602001614965969594939291906157f8565b60408051601f1981840301815291905280516020909101209695505050505050565b6000806401000003d01980848509840990506401000003d019600782089392505050565b6149b3614e99565b6149bc82614bd7565b81526149d16149cc8260006146ab565b614c12565b602082018190526002900660011415612018576020810180516401000003d019039052919050565b600082614a365760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b604482015260640161097e565b83516020850151600090614a4c90600290615e27565b15614a5857601c614a5b565b601b5b9050600070014551231950b75fc4402da1732fc9bebe19838709604080516000808252602090910191829052919250600190614a9e90839086908890879061590b565b6020604051602081039080840390855afa158015614ac0573d6000803e3d6000fd5b505050602060405103519050600086604051602001614adf91906157e6565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614b1c614e99565b835160208086015185519186015160009384938493614b3d93909190614c32565b919450925090506401000003d019858209600114614b995760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b604482015260640161097e565b60405180604001604052806401000003d01980614bb857614bb8615e51565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d019811061201857604080516020808201939093528151808203840181529082019091528051910120614bdf565b600061103b826002614c2b6401000003d0196001615cde565b901c614d12565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614c7283838585614da9565b9098509050614c8388828e88614dcd565b9098509050614c9488828c87614dcd565b90985090506000614ca78d878b85614dcd565b9098509050614cb888828686614da9565b9098509050614cc988828e89614dcd565b9098509050818114614cfe576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614d02565b8196505b5050505050509450945094915050565b600080614d1d614eb7565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614d4f614ed5565b60208160c0846005600019fa925082614d9f5760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b604482015260640161097e565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614e6b579160200282015b82811115614e6b57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614e36565b50614e77929150614ef3565b5090565b50805460008255906000526020600020908101906124689190614ef3565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614e775760008155600101614ef4565b803561201881615ea9565b600082601f830112614f2457600080fd5b813560206001600160401b03821115614f3f57614f3f615e93565b8160051b614f4e828201615c84565b838152828101908684018388018501891015614f6957600080fd5b600093505b85841015614f95578035614f8181615ea9565b835260019390930192918401918401614f6e565b50979650505050505050565b600082601f830112614fb257600080fd5b614fba615c17565b808385604086011115614fcc57600080fd5b60005b6002811015614fee578135845260209384019390910190600101614fcf565b509095945050505050565b60008083601f84011261500b57600080fd5b5081356001600160401b0381111561502257600080fd5b60208301915083602082850101111561503a57600080fd5b9250929050565b600082601f83011261505257600080fd5b81356001600160401b0381111561506b5761506b615e93565b61507e601f8201601f1916602001615c84565b81815284602083860101111561509357600080fd5b816020850160208301376000918101602001919091529392505050565b600060c082840312156150c257600080fd5b6150ca615c3f565b905081356001600160401b0380821682146150e457600080fd5b818352602084013560208401526150fd60408501615163565b604084015261510e60608501615163565b606084015261511f60808501614f08565b608084015260a084013591508082111561513857600080fd5b5061514584828501615041565b60a08301525092915050565b803561ffff8116811461201857600080fd5b803563ffffffff8116811461201857600080fd5b80516001600160501b038116811461201857600080fd5b80356001600160601b038116811461201857600080fd5b6000602082840312156151b757600080fd5b813561385681615ea9565b600080604083850312156151d557600080fd5b82356151e081615ea9565b91506151ee6020840161518e565b90509250929050565b6000806040838503121561520a57600080fd5b823561521581615ea9565b9150602083013561522581615ea9565b809150509250929050565b6000806060838503121561524357600080fd5b823561524e81615ea9565b91506060830184101561526057600080fd5b50926020919091019150565b6000806000806060858703121561528257600080fd5b843561528d81615ea9565b93506020850135925060408501356001600160401b038111156152af57600080fd5b6152bb87828801614ff9565b95989497509550505050565b6000604082840312156152d957600080fd5b6138568383614fa1565b6000602082840312156152f557600080fd5b815161385681615ebe565b60006020828403121561531257600080fd5b5035919050565b60006020828403121561532b57600080fd5b5051919050565b6000806020838503121561534557600080fd5b82356001600160401b0381111561535b57600080fd5b61536785828601614ff9565b90969095509350505050565b60006020828403121561538557600080fd5b604051602081016001600160401b03811182821017156153a7576153a7615e93565b60405282356153b581615ebe565b81529392505050565b6000808284036101c08112156153d357600080fd5b6101a0808212156153e357600080fd5b6153eb615c61565b91506153f78686614fa1565b82526154068660408701614fa1565b60208301526080850135604083015260a0850135606083015260c0850135608083015261543560e08601614f08565b60a083015261010061544987828801614fa1565b60c084015261545c876101408801614fa1565b60e0840152610180860135908301529092508301356001600160401b0381111561548557600080fd5b615491858286016150b0565b9150509250929050565b6000602082840312156154ad57600080fd5b81356001600160401b038111156154c357600080fd5b820160c0818503121561385657600080fd5b6000602082840312156154e757600080fd5b81356001600160401b03808211156154fe57600080fd5b9083019060c0828603121561551257600080fd5b61551a615c3f565b823560ff8116811461552b57600080fd5b81526020838101359082015261554360408401614f08565b604082015260608301358281111561555a57600080fd5b61556687828601614f13565b6060830152506155786080840161518e565b608082015261558960a0840161518e565b60a082015295945050505050565b6000602082840312156155a957600080fd5b61385682615151565b60008060008060008086880360e08112156155cc57600080fd5b6155d588615151565b96506155e360208901615163565b95506155f160408901615163565b94506155ff60608901615163565b9350608088013592506040609f198201121561561a57600080fd5b50615623615c17565b61562f60a08901615163565b815261563d60c08901615163565b6020820152809150509295509295509295565b6000806040838503121561566357600080fd5b82359150602083013561522581615ea9565b6000806040838503121561568857600080fd5b50508035926020909101359150565b6000602082840312156156a957600080fd5b61385682615163565b600080600080600060a086880312156156ca57600080fd5b6156d386615177565b94506020860151935060408601519250606086015191506156f660808701615177565b90509295509295909350565b600081518084526020808501945080840160005b8381101561573b5781516001600160a01b031687529582019590820190600101615716565b509495945050505050565b8060005b60028110156109e357815184526020938401939091019060010161574a565b600081518084526020808501945080840160005b8381101561573b5781518752958201959082019060010161577d565b6000815180845260005b818110156157bf576020818501810151868301820152016157a3565b818111156157d1576000602083870101525b50601f01601f19169290920160200192915050565b6157f08183615746565b604001919050565b8681526158086020820187615746565b6158156060820186615746565b61582260a0820185615746565b61582f60e0820184615746565b60609190911b6001600160601b0319166101208201526101340195945050505050565b8381526158626020820184615746565b606081019190915260800192915050565b6001600160a01b0391909116815260200190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6040810161103b8284615746565b6020815260006138566020830184615769565b918252602082015260400190565b93845260ff9290921660208401526040830152606082015260800190565b6020815260006138566020830184615799565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261598160e0840182615702565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b61ffff93841681529183166020830152909116604082015260600190565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015615a2057845183529383019391830191600101615a04565b509098975050505050505050565b9182526001600160a01b0316602082015260400190565b828152606081016138566020830184615746565b8281526040602082015260006138a46040830184615769565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a083015261402c60c0830184615799565b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c0820181905260009061411890830184615799565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c0820181905260009061411890830184615799565b63ffffffff92831681529116602082015260400190565b6001600160401b0391909116815260200190565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a060808201819052600090615bc690830184615702565b979650505050505050565b6000808335601e19843603018112615be857600080fd5b8301803591506001600160401b03821115615c0257600080fd5b60200191503681900382131561503a57600080fd5b604080519081016001600160401b0381118282101715615c3957615c39615e93565b60405290565b60405160c081016001600160401b0381118282101715615c3957615c39615e93565b60405161012081016001600160401b0381118282101715615c3957615c39615e93565b604051601f8201601f191681016001600160401b0381118282101715615cac57615cac615e93565b604052919050565b60008085851115615cc457600080fd5b83861115615cd157600080fd5b5050820193919092039150565b60008219821115615cf157615cf1615e3b565b500190565b60006001600160401b03828116848216808303821115615d1857615d18615e3b565b01949350505050565b60006001600160601b03828116848216808303821115615d1857615d18615e3b565b600082615d5257615d52615e51565b500490565b6000816000190483118215151615615d7157615d71615e3b565b500290565b600082821015615d8857615d88615e3b565b500390565b60006001600160601b0383811690831681811015615dad57615dad615e3b565b039392505050565b6001600160e01b03198135818116916004851015615ddd5780818660040360031b1b83161692505b505092915050565b6000600019821415615df957615df9615e3b565b5060010190565b60006001600160401b0382811680821415615e1d57615e1d615e3b565b6001019392505050565b600082615e3657615e36615e51565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461246857600080fd5b801515811461246857600080fdfea164736f6c6343000806000a", } var VRFCoordinatorV2PlusUpgradedVersionABI = VRFCoordinatorV2PlusUpgradedVersionMetaData.ABI @@ -250,9 +250,9 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC return _VRFCoordinatorV2PlusUpgradedVersion.Contract.LINK(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) LINKETHFEED(opts *bind.CallOpts) (common.Address, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "LINK_ETH_FEED") + err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "LINK_NATIVE_FEED") if err != nil { return *new(common.Address), err @@ -264,12 +264,12 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) LINKETHFEED() (common.Address, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.LINKETHFEED(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) LINKNATIVEFEED() (common.Address, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.LINKNATIVEFEED(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) LINKETHFEED() (common.Address, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.LINKETHFEED(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) LINKNATIVEFEED() (common.Address, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.LINKNATIVEFEED(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) { @@ -396,7 +396,7 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC } outstruct.Balance = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) - outstruct.EthBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.NativeBalance = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) 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) @@ -594,7 +594,7 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC } outstruct.FulfillmentFlatFeeLinkPPM = *abi.ConvertType(out[0], new(uint32)).(*uint32) - outstruct.FulfillmentFlatFeeEthPPM = *abi.ConvertType(out[1], new(uint32)).(*uint32) + outstruct.FulfillmentFlatFeeNativePPM = *abi.ConvertType(out[1], new(uint32)).(*uint32) return *outstruct, err @@ -700,9 +700,9 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC return _VRFCoordinatorV2PlusUpgradedVersion.Contract.STotalBalance(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) STotalEthBalance(opts *bind.CallOpts) (*big.Int, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_totalEthBalance") + err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_totalNativeBalance") if err != nil { return *new(*big.Int), err @@ -714,12 +714,12 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) STotalEthBalance() (*big.Int, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.STotalEthBalance(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.STotalNativeBalance(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) STotalEthBalance() (*big.Int, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.STotalEthBalance(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) STotalNativeBalance() (*big.Int, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.STotalNativeBalance(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { @@ -794,16 +794,16 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionT return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FundSubscriptionWithEth(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "fundSubscriptionWithEth", subId) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "fundSubscriptionWithNative", subId) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) FundSubscriptionWithEth(subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FundSubscriptionWithEth(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FundSubscriptionWithNative(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) FundSubscriptionWithEth(subId *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FundSubscriptionWithEth(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) FundSubscriptionWithNative(subId *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FundSubscriptionWithNative(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId) } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) { @@ -854,16 +854,16 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionT return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OracleWithdraw(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, recipient, amount) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) OracleWithdrawEth(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "oracleWithdrawEth", recipient, amount) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) OracleWithdrawNative(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "oracleWithdrawNative", recipient, amount) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) OracleWithdrawEth(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OracleWithdrawEth(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, recipient, amount) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) OracleWithdrawNative(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OracleWithdrawNative(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, recipient, amount) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) OracleWithdrawEth(recipient common.Address, amount *big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OracleWithdrawEth(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, recipient, amount) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) OracleWithdrawNative(recipient common.Address, amount *big.Int) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OracleWithdrawNative(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, recipient, amount) } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { @@ -878,18 +878,6 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionT return _VRFCoordinatorV2PlusUpgradedVersion.Contract.OwnerCancelSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, subId) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RecoverEthFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "recoverEthFunds", to) -} - -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RecoverEthFunds(to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RecoverEthFunds(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, to) -} - -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RecoverEthFunds(to common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RecoverEthFunds(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, to) -} - func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "recoverFunds", to) } @@ -902,6 +890,18 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionT return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RecoverFunds(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, to) } +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RecoverNativeFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "recoverNativeFunds", to) +} + +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RecoverNativeFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RecoverNativeFunds(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, to) +} + +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RecoverNativeFunds(to common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RecoverNativeFunds(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, to) +} + func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) { return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "registerMigratableCoordinator", target) } @@ -974,16 +974,16 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionT return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SetConfig(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, minimumRequestConfirmations, maxGasLimit, stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, feeConfig) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) SetLINKAndLINKETHFeed(opts *bind.TransactOpts, link common.Address, linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "setLINKAndLINKETHFeed", link, linkEthFeed) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) SetLINKAndLINKNativeFeed(opts *bind.TransactOpts, link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "setLINKAndLINKNativeFeed", link, linkNativeFeed) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SetLINKAndLINKETHFeed(link common.Address, linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SetLINKAndLINKETHFeed(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, link, linkEthFeed) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SetLINKAndLINKNativeFeed(link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SetLINKAndLINKNativeFeed(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, link, linkNativeFeed) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) SetLINKAndLINKETHFeed(link common.Address, linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SetLINKAndLINKETHFeed(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, link, linkEthFeed) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) SetLINKAndLINKNativeFeed(link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SetLINKAndLINKNativeFeed(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, link, linkNativeFeed) } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { @@ -1237,8 +1237,8 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF return event, nil } -type VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator struct { - Event *VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered +type VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator struct { + Event *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered contract *bind.BoundContract event string @@ -1249,7 +1249,7 @@ type VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator struct { fail error } -func (it *VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator) Next() bool { +func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Next() bool { if it.fail != nil { return false @@ -1258,7 +1258,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator) Next() b if it.done { select { case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered) + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1273,7 +1273,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator) Next() b select { case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered) + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1288,33 +1288,33 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator) Next() b } } -func (it *VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator) Error() error { +func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Error() error { return it.fail } -func (it *VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator) Close() error { +func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Close() error { it.sub.Unsubscribe() return nil } -type VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered struct { +type VRFCoordinatorV2PlusUpgradedVersionFundsRecovered struct { To common.Address Amount *big.Int Raw types.Log } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterEthFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator, error) { - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "EthFundsRecovered") + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "FundsRecovered") if err != nil { return nil, err } - return &VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "EthFundsRecovered", logs: logs, sub: sub}, nil + return &VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchEthFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered) (event.Subscription, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) (event.Subscription, error) { - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "EthFundsRecovered") + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "FundsRecovered") if err != nil { return nil, err } @@ -1324,8 +1324,8 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF select { case log := <-logs: - event := new(VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered) - if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "EthFundsRecovered", log); err != nil { + event := new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "FundsRecovered", log); err != nil { return err } event.Raw = log @@ -1346,17 +1346,17 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF }), nil } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseEthFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered, error) { - event := new(VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered) - if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "EthFundsRecovered", log); err != nil { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecovered, error) { + event := new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "FundsRecovered", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator struct { - Event *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered +type VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator struct { + Event *VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted contract *bind.BoundContract event string @@ -1367,7 +1367,7 @@ type VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator struct { fail error } -func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Next() bool { +func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Next() bool { if it.fail != nil { return false @@ -1376,7 +1376,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Next() bool if it.done { select { case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1391,7 +1391,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Next() bool select { case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1406,33 +1406,33 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Next() bool } } -func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Error() error { +func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Error() error { return it.fail } -func (it *VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator) Close() error { +func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Close() error { it.sub.Unsubscribe() return nil } -type VRFCoordinatorV2PlusUpgradedVersionFundsRecovered struct { - To common.Address - Amount *big.Int - Raw types.Log +type VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted struct { + NewCoordinator common.Address + SubId *big.Int + Raw types.Log } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator, error) { - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "FundsRecovered") + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "MigrationCompleted") if err != nil { return nil, err } - return &VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "FundsRecovered", logs: logs, sub: sub}, nil + return &VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "MigrationCompleted", logs: logs, sub: sub}, nil } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) (event.Subscription, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) (event.Subscription, error) { - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "FundsRecovered") + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "MigrationCompleted") if err != nil { return nil, err } @@ -1442,8 +1442,8 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF select { case log := <-logs: - event := new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) - if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "FundsRecovered", log); err != nil { + event := new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { return err } event.Raw = log @@ -1464,17 +1464,17 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF }), nil } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecovered, error) { - event := new(VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) - if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "FundsRecovered", log); err != nil { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseMigrationCompleted(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted, error) { + event := new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { return nil, err } event.Raw = log return event, nil } -type VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator struct { - Event *VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted +type VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator struct { + Event *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered contract *bind.BoundContract event string @@ -1485,7 +1485,7 @@ type VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator struct { fail error } -func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Next() bool { +func (it *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator) Next() bool { if it.fail != nil { return false @@ -1494,7 +1494,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Next() if it.done { select { case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1509,7 +1509,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Next() select { case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1524,33 +1524,33 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Next() } } -func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Error() error { +func (it *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator) Error() error { return it.fail } -func (it *VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator) Close() error { +func (it *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator) Close() error { it.sub.Unsubscribe() return nil } -type VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted struct { - NewCoordinator common.Address - SubId *big.Int - Raw types.Log +type VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered struct { + To common.Address + Amount *big.Int + Raw types.Log } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterMigrationCompleted(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterNativeFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator, error) { - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "MigrationCompleted") + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "NativeFundsRecovered") if err != nil { return nil, err } - return &VRFCoordinatorV2PlusUpgradedVersionMigrationCompletedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "MigrationCompleted", logs: logs, sub: sub}, nil + return &VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "NativeFundsRecovered", logs: logs, sub: sub}, nil } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchMigrationCompleted(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) (event.Subscription, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchNativeFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered) (event.Subscription, error) { - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "MigrationCompleted") + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "NativeFundsRecovered") if err != nil { return nil, err } @@ -1560,8 +1560,8 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF select { case log := <-logs: - event := new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) - if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { + event := new(VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "NativeFundsRecovered", log); err != nil { return err } event.Raw = log @@ -1582,9 +1582,9 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF }), nil } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseMigrationCompleted(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted, error) { - event := new(VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) - if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "MigrationCompleted", log); err != nil { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseNativeFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered, error) { + event := new(VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "NativeFundsRecovered", log); err != nil { return nil, err } event.Raw = log @@ -2348,11 +2348,11 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceledIterator) Close } type VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceled struct { - SubId *big.Int - To common.Address - AmountLink *big.Int - AmountEth *big.Int - Raw types.Log + SubId *big.Int + To common.Address + AmountLink *big.Int + AmountNative *big.Int + Raw types.Log } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterSubscriptionCanceled(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionCanceledIterator, error) { @@ -2930,8 +2930,8 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF return event, nil } -type VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator struct { - Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth +type VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator struct { + Event *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative contract *bind.BoundContract event string @@ -2942,7 +2942,7 @@ type VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator struct fail error } -func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator) Next() bool { +func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator) Next() bool { if it.fail != nil { return false @@ -2951,7 +2951,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator) if it.done { select { case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth) + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2966,7 +2966,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator) select { case log := <-it.logs: - it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth) + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -2981,44 +2981,44 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator) } } -func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator) Error() error { +func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator) Error() error { return it.fail } -func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator) Close() error { +func (it *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator) Close() error { it.sub.Unsubscribe() return nil } -type VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth struct { - SubId *big.Int - OldEthBalance *big.Int - NewEthBalance *big.Int - Raw types.Log +type VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative struct { + SubId *big.Int + OldNativeBalance *big.Int + NewNativeBalance *big.Int + Raw types.Log } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterSubscriptionFundedWithEth(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterSubscriptionFundedWithNative(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator, error) { var subIdRule []interface{} for _, subIdItem := range subId { subIdRule = append(subIdRule, subIdItem) } - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "SubscriptionFundedWithEth", subIdRule) + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "SubscriptionFundedWithNative", subIdRule) if err != nil { return nil, err } - return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionFundedWithEth", logs: logs, sub: sub}, nil + return &VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "SubscriptionFundedWithNative", logs: logs, sub: sub}, nil } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchSubscriptionFundedWithEth(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth, subId []*big.Int) (event.Subscription, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchSubscriptionFundedWithNative(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative, subId []*big.Int) (event.Subscription, error) { var subIdRule []interface{} for _, subIdItem := range subId { subIdRule = append(subIdRule, subIdItem) } - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "SubscriptionFundedWithEth", subIdRule) + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "SubscriptionFundedWithNative", subIdRule) if err != nil { return nil, err } @@ -3028,8 +3028,8 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF select { case log := <-logs: - event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth) - if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionFundedWithEth", log); err != nil { + event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionFundedWithNative", log); err != nil { return err } event.Raw = log @@ -3050,9 +3050,9 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF }), nil } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseSubscriptionFundedWithEth(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth, error) { - event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth) - if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionFundedWithEth", log); err != nil { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseSubscriptionFundedWithNative(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative, error) { + event := new(VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "SubscriptionFundedWithNative", log); err != nil { return nil, err } event.Raw = log @@ -3318,11 +3318,11 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF } type GetSubscription struct { - Balance *big.Int - EthBalance *big.Int - ReqCount uint64 - Owner common.Address - Consumers []common.Address + Balance *big.Int + NativeBalance *big.Int + ReqCount uint64 + Owner common.Address + Consumers []common.Address } type SConfig struct { MinimumRequestConfirmations uint16 @@ -3332,8 +3332,8 @@ type SConfig struct { GasAfterPaymentCalculation uint32 } type SFeeConfig struct { - FulfillmentFlatFeeLinkPPM uint32 - FulfillmentFlatFeeEthPPM uint32 + FulfillmentFlatFeeLinkPPM uint32 + FulfillmentFlatFeeNativePPM uint32 } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion) ParseLog(log types.Log) (generated.AbigenLog, error) { @@ -3342,12 +3342,12 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion) return _VRFCoordinatorV2PlusUpgradedVersion.ParseConfigSet(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["CoordinatorRegistered"].ID: return _VRFCoordinatorV2PlusUpgradedVersion.ParseCoordinatorRegistered(log) - case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["EthFundsRecovered"].ID: - return _VRFCoordinatorV2PlusUpgradedVersion.ParseEthFundsRecovered(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["FundsRecovered"].ID: return _VRFCoordinatorV2PlusUpgradedVersion.ParseFundsRecovered(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["MigrationCompleted"].ID: return _VRFCoordinatorV2PlusUpgradedVersion.ParseMigrationCompleted(log) + case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["NativeFundsRecovered"].ID: + return _VRFCoordinatorV2PlusUpgradedVersion.ParseNativeFundsRecovered(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["OwnershipTransferRequested"].ID: return _VRFCoordinatorV2PlusUpgradedVersion.ParseOwnershipTransferRequested(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["OwnershipTransferred"].ID: @@ -3368,8 +3368,8 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion) return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionCreated(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionFunded"].ID: return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionFunded(log) - case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionFundedWithEth"].ID: - return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionFundedWithEth(log) + case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionFundedWithNative"].ID: + return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionFundedWithNative(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionOwnerTransferRequested"].ID: return _VRFCoordinatorV2PlusUpgradedVersion.ParseSubscriptionOwnerTransferRequested(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["SubscriptionOwnerTransferred"].ID: @@ -3388,10 +3388,6 @@ func (VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered) Topic() common.H return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625") } -func (VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered) Topic() common.Hash { - return common.HexToHash("0x879c9ea2b9d5345b84ccd12610b032602808517cebdb795007f3dcb4df377317") -} - func (VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) Topic() common.Hash { return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600") } @@ -3400,6 +3396,10 @@ func (VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) Topic() common.Hash return common.HexToHash("0xd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187") } +func (VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered) Topic() common.Hash { + return common.HexToHash("0x4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c") +} + func (VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested) Topic() common.Hash { return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") } @@ -3440,8 +3440,8 @@ func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded) Topic() common.Hash return common.HexToHash("0x1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a") } -func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth) Topic() common.Hash { - return common.HexToHash("0x3f1ddc3ab1bdb39001ad76ca51a0e6f57ce6627c69f251d1de41622847721cde") +func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative) Topic() common.Hash { + return common.HexToHash("0x7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902") } func (VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequested) Topic() common.Hash { @@ -3461,7 +3461,7 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { LINK(opts *bind.CallOpts) (common.Address, error) - LINKETHFEED(opts *bind.CallOpts) (common.Address, error) + LINKNATIVEFEED(opts *bind.CallOpts) (common.Address, error) MAXCONSUMERS(opts *bind.CallOpts) (uint16, error) @@ -3505,7 +3505,7 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { STotalBalance(opts *bind.CallOpts) (*big.Int, error) - STotalEthBalance(opts *bind.CallOpts) (*big.Int, error) + STotalNativeBalance(opts *bind.CallOpts) (*big.Int, error) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) @@ -3519,7 +3519,7 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment) (*types.Transaction, error) - FundSubscriptionWithEth(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) + FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) Migrate(opts *bind.TransactOpts, subId *big.Int, newCoordinator common.Address) (*types.Transaction, error) @@ -3529,14 +3529,14 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) - OracleWithdrawEth(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) + OracleWithdrawNative(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) OwnerCancelSubscription(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) - RecoverEthFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) - RecoverFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + RecoverNativeFunds(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) RegisterProvingKey(opts *bind.TransactOpts, oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) @@ -3549,7 +3549,7 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { SetConfig(opts *bind.TransactOpts, minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig VRFCoordinatorV2PlusUpgradedVersionFeeConfig) (*types.Transaction, error) - SetLINKAndLINKETHFeed(opts *bind.TransactOpts, link common.Address, linkEthFeed common.Address) (*types.Transaction, error) + SetLINKAndLINKNativeFeed(opts *bind.TransactOpts, link common.Address, linkNativeFeed common.Address) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -3565,12 +3565,6 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered, error) - FilterEthFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionEthFundsRecoveredIterator, error) - - WatchEthFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered) (event.Subscription, error) - - ParseEthFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionEthFundsRecovered, error) - FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator, error) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) (event.Subscription, error) @@ -3583,6 +3577,12 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { ParseMigrationCompleted(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted, error) + FilterNativeFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecoveredIterator, error) + + WatchNativeFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered) (event.Subscription, error) + + ParseNativeFundsRecovered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionNativeFundsRecovered, error) + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequestedIterator, error) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) @@ -3643,11 +3643,11 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { ParseSubscriptionFunded(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFunded, error) - FilterSubscriptionFundedWithEth(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEthIterator, error) + FilterSubscriptionFundedWithNative(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNativeIterator, error) - WatchSubscriptionFundedWithEth(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth, subId []*big.Int) (event.Subscription, error) + WatchSubscriptionFundedWithNative(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative, subId []*big.Int) (event.Subscription, error) - ParseSubscriptionFundedWithEth(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithEth, error) + ParseSubscriptionFundedWithNative(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionFundedWithNative, error) FilterSubscriptionOwnerTransferRequested(opts *bind.FilterOpts, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionSubscriptionOwnerTransferRequestedIterator, error) diff --git a/core/gethwrappers/generated/vrfv2_wrapper/vrfv2_wrapper.go b/core/gethwrappers/generated/vrfv2_wrapper/vrfv2_wrapper.go index e50c335e03..9ce091f8a5 100644 --- a/core/gethwrappers/generated/vrfv2_wrapper/vrfv2_wrapper.go +++ b/core/gethwrappers/generated/vrfv2_wrapper/vrfv2_wrapper.go @@ -32,7 +32,7 @@ var ( var VRFV2WrapperMetaData = &bind.MetaData{ ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkEthFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coordinator\",\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"WrapperFulfillmentFailed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"COORDINATOR\",\"outputs\":[{\"internalType\":\"contractExtendedVRFCoordinatorV2Interface\",\"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\":\"SUBSCRIPTION_ID\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"enable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"maxNumWords\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_callbacks\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"requestGasPrice\",\"type\":\"uint256\"},{\"internalType\":\"int256\",\"name\":\"requestWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint256\",\"name\":\"juelsPaid\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_configured\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_disabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fulfillmentTxSizeBytes\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"_wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"_maxNumWords\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"size\",\"type\":\"uint32\"}],\"name\":\"setFulfillmentTxSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6101206040526001805463ffffffff60a01b1916609160a21b1790553480156200002857600080fd5b50604051620025d0380380620025d08339810160408190526200004b91620002d8565b803380600081620000a35760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d657620000d6816200020f565b5050506001600160601b0319606091821b811660805284821b811660a05283821b811660c0529082901b1660e0526040805163288688f960e21b815290516000916001600160a01b0384169163a21a23e49160048082019260209290919082900301818787803b1580156200014a57600080fd5b505af11580156200015f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000185919062000322565b60c081901b6001600160c01b03191661010052604051631cd0704360e21b81526001600160401b03821660048201523060248201529091506001600160a01b03831690637341c10c90604401600060405180830381600087803b158015620001ec57600080fd5b505af115801562000201573d6000803e3d6000fd5b505050505050505062000354565b6001600160a01b0381163314156200026a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620002d357600080fd5b919050565b600080600060608486031215620002ee57600080fd5b620002f984620002bb565b92506200030960208501620002bb565b91506200031960408501620002bb565b90509250925092565b6000602082840312156200033557600080fd5b81516001600160401b03811681146200034d57600080fd5b9392505050565b60805160601c60a05160601c60c05160601c60e05160601c6101005160c01c6121e9620003e7600039600081816101970152610c5501526000818161028401528181610c1601528181610fec015281816110cd01526111680152600081816103fd015261161c01526000818161021b01528181610a6801526112ba01526000818161055801526105c001526121e96000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c80638da5cb5b116100e3578063c15ce4d71161008c578063f2fde38b11610066578063f2fde38b14610511578063f3fef3a314610524578063fc2a88c31461053757600080fd5b8063c15ce4d714610432578063c3f909d414610445578063cdd8d885146104d457600080fd5b8063a608a1e1116100bd578063a608a1e1146103e6578063ad178361146103f8578063bf17e5591461041f57600080fd5b80638da5cb5b146103ad578063a3907d71146103cb578063a4c0ed36146103d357600080fd5b80633b2bcbf11161014557806357a8070a1161011f57806357a8070a1461037557806379ba5097146103925780637fb5d19d1461039a57600080fd5b80633b2bcbf11461027f5780634306d354146102a657806348baa1c5146102c757600080fd5b80631b6b6d23116101765780631b6b6d23146102165780631fe543e3146102625780632f2770db1461027757600080fd5b8063030932bb14610192578063181f5a77146101d7575b600080fd5b6101b97f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b604080518082018252601281527f56524656325772617070657220312e302e300000000000000000000000000000602082015290516101ce9190611f7c565b61023d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ce565b610275610270366004611c61565b610540565b005b610275610600565b61023d7f000000000000000000000000000000000000000000000000000000000000000081565b6102b96102b4366004611d9a565b610636565b6040519081526020016101ce565b6103316102d5366004611c48565b600860205260009081526040902080546001820154600283015460039093015473ffffffffffffffffffffffffffffffffffffffff8316937401000000000000000000000000000000000000000090930463ffffffff16929085565b6040805173ffffffffffffffffffffffffffffffffffffffff909616865263ffffffff9094166020860152928401919091526060830152608082015260a0016101ce565b6003546103829060ff1681565b60405190151581526020016101ce565b61027561073d565b6102b96103a8366004611e02565b61083a565b60005473ffffffffffffffffffffffffffffffffffffffff1661023d565b610275610940565b6102756103e1366004611b27565b610972565b60035461038290610100900460ff1681565b61023d7f000000000000000000000000000000000000000000000000000000000000000081565b61027561042d366004611d9a565b610e50565b610275610440366004611ed6565b610ea7565b6004546005546006546007546040805194855263ffffffff80851660208701526401000000008504811691860191909152680100000000000000008404811660608601526c01000000000000000000000000840416608085015260ff700100000000000000000000000000000000909304831660a085015260c08401919091521660e0820152610100016101ce565b6001546104fc9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016101ce565b61027561051f366004611ae2565b611252565b610275610532366004611afd565b611266565b6102b960025481565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146105f2576040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044015b60405180910390fd5b6105fc828261133b565b5050565b610608611546565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60035460009060ff166106a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e666967757265640000000000000060448201526064016105e9565b600354610100900460ff1615610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c65640000000000000000000000000060448201526064016105e9565b60006107216115c9565b90506107348363ffffffff163a8361173d565b9150505b919050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016105e9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60035460009060ff166108a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e666967757265640000000000000060448201526064016105e9565b600354610100900460ff161561091b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c65640000000000000000000000000060448201526064016105e9565b60006109256115c9565b90506109388463ffffffff16848361173d565b949350505050565b610948611546565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055565b60035460ff166109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e666967757265640000000000000060448201526064016105e9565b600354610100900460ff1615610a50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c65640000000000000000000000000060448201526064016105e9565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610aef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b00000000000000000060448201526064016105e9565b60008080610aff84860186611db7565b9250925092506000610b108461185e565b90506000610b1c6115c9565b90506000610b318663ffffffff163a8461173d565b905080891015610b9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f7700000000000000000000000000000000000000000060448201526064016105e9565b60075460ff1663ffffffff85161115610c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f206869676800000000000000000000000000000060448201526064016105e9565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635d3b1d306006547f000000000000000000000000000000000000000000000000000000000000000089600560089054906101000a900463ffffffff16898d610c949190612055565b610c9e9190612055565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b168152600481019490945267ffffffffffffffff909216602484015261ffff16604483015263ffffffff90811660648301528816608482015260a401602060405180830381600087803b158015610d1d57600080fd5b505af1158015610d31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d559190611bd0565b90506040518060a001604052808c73ffffffffffffffffffffffffffffffffffffffff1681526020018863ffffffff1681526020013a81526020018481526020018b8152506008600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff160217905550604082015181600101556060820151816002015560808201518160030155905050806002819055505050505050505050505050565b610e58611546565b6001805463ffffffff90921674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b610eaf611546565b6005805460ff808616700100000000000000000000000000000000027fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff63ffffffff8981166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff918c166801000000000000000002919091167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff909516949094179390931792909216919091179091556006839055600780549183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00928316179055600380549091166001179055604080517fc3f909d4000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163c3f909d4916004828101926080929190829003018186803b15801561103257600080fd5b505afa158015611046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106a9190611be9565b50600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790555050604080517f356dac7100000000000000000000000000000000000000000000000000000000815290517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169163356dac71916004808301926020929190829003018186803b15801561112857600080fd5b505afa15801561113c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111609190611bd0565b6004819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635fbbc0d26040518163ffffffff1660e01b81526004016101206040518083038186803b1580156111cd57600080fd5b505afa1580156111e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112059190611e20565b50506005805463ffffffff909816640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff909816979097179096555050505050505050505050565b61125a611546565b6112638161187c565b50565b61126e611546565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b1580156112fe57600080fd5b505af1158015611312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113369190611bae565b505050565b6000828152600860208181526040808420815160a081018352815473ffffffffffffffffffffffffffffffffffffffff808216835263ffffffff740100000000000000000000000000000000000000008304168387015260018401805495840195909552600284018054606085015260038501805460808601528b8a52979096527fffffffffffffffff000000000000000000000000000000000000000000000000909116909255918590559184905592909155815116611458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e6400000000000000000000000000000060448201526064016105e9565b600080631fe543e360e01b8585604051602401611476929190611fef565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060006114f0846020015163ffffffff16856000015184611972565b90508061153e57835160405173ffffffffffffffffffffffffffffffffffffffff9091169087907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146115c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105e9565b565b600554604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009263ffffffff161515918391829173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163feaf968c9160048082019260a092909190829003018186803b15801561166357600080fd5b505afa158015611677573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169b9190611f38565b5094509092508491505080156116c157506116b68242612116565b60055463ffffffff16105b156116cb57506004545b6000811215611736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b207765692070726963650000000000000000000060448201526064016105e9565b9392505050565b600154600090819061176c9074010000000000000000000000000000000000000000900463ffffffff166119be565b60055463ffffffff6c01000000000000000000000000820481169161179f9168010000000000000000909104168861203d565b6117a9919061203d565b6117b390866120d9565b6117bd919061203d565b90506000836117d483670de0b6b3a76400006120d9565b6117de91906120a2565b60055490915060009060649061180b90700100000000000000000000000000000000900460ff168261207d565b6118189060ff16846120d9565b61182291906120a2565b60055490915060009061184890640100000000900463ffffffff1664e8d4a510006120d9565b611852908361203d565b98975050505050505050565b600061186b603f836120b6565b611876906001612055565b92915050565b73ffffffffffffffffffffffffffffffffffffffff81163314156118fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105e9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005a61138881101561198457600080fd5b61138881039050846040820482031161199c57600080fd5b50823b6119a857600080fd5b60008083516020850160008789f1949350505050565b60004661a4b18114806119d3575062066eed81145b15611a77576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c06040518083038186803b158015611a2157600080fd5b505afa158015611a35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a599190611d50565b5050505091505083608c611a6d919061203d565b61093890826120d9565b50600092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461073857600080fd5b805162ffffff8116811461073857600080fd5b803560ff8116811461073857600080fd5b805169ffffffffffffffffffff8116811461073857600080fd5b600060208284031215611af457600080fd5b61173682611a80565b60008060408385031215611b1057600080fd5b611b1983611a80565b946020939093013593505050565b60008060008060608587031215611b3d57600080fd5b611b4685611a80565b935060208501359250604085013567ffffffffffffffff80821115611b6a57600080fd5b818701915087601f830112611b7e57600080fd5b813581811115611b8d57600080fd5b886020828501011115611b9f57600080fd5b95989497505060200194505050565b600060208284031215611bc057600080fd5b8151801515811461173657600080fd5b600060208284031215611be257600080fd5b5051919050565b60008060008060808587031215611bff57600080fd5b8451611c0a816121ba565b6020860151909450611c1b816121ca565b6040860151909350611c2c816121ca565b6060860151909250611c3d816121ca565b939692955090935050565b600060208284031215611c5a57600080fd5b5035919050565b60008060408385031215611c7457600080fd5b8235915060208084013567ffffffffffffffff80821115611c9457600080fd5b818601915086601f830112611ca857600080fd5b813581811115611cba57611cba61218b565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715611cfd57611cfd61218b565b604052828152858101935084860182860187018b1015611d1c57600080fd5b600095505b83861015611d3f578035855260019590950194938601938601611d21565b508096505050505050509250929050565b60008060008060008060c08789031215611d6957600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060208284031215611dac57600080fd5b8135611736816121ca565b600080600060608486031215611dcc57600080fd5b8335611dd7816121ca565b92506020840135611de7816121ba565b91506040840135611df7816121ca565b809150509250925092565b60008060408385031215611e1557600080fd5b8235611b19816121ca565b60008060008060008060008060006101208a8c031215611e3f57600080fd5b8951611e4a816121ca565b60208b0151909950611e5b816121ca565b60408b0151909850611e6c816121ca565b60608b0151909750611e7d816121ca565b60808b0151909650611e8e816121ca565b9450611e9c60a08b01611aa4565b9350611eaa60c08b01611aa4565b9250611eb860e08b01611aa4565b9150611ec76101008b01611aa4565b90509295985092959850929598565b600080600080600060a08688031215611eee57600080fd5b8535611ef9816121ca565b94506020860135611f09816121ca565b9350611f1760408701611ab7565b925060608601359150611f2c60808701611ab7565b90509295509295909350565b600080600080600060a08688031215611f5057600080fd5b611f5986611ac8565b9450602086015193506040860151925060608601519150611f2c60808701611ac8565b600060208083528351808285015260005b81811015611fa957858101830151858201604001528201611f8d565b81811115611fbb576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561203057845183529383019391830191600101612014565b5090979650505050505050565b600082198211156120505761205061212d565b500190565b600063ffffffff8083168185168083038211156120745761207461212d565b01949350505050565b600060ff821660ff84168060ff0382111561209a5761209a61212d565b019392505050565b6000826120b1576120b161215c565b500490565b600063ffffffff808416806120cd576120cd61215c565b92169190910492915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156121115761211161212d565b500290565b6000828210156121285761212861212d565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61ffff8116811461126357600080fd5b63ffffffff8116811461126357600080fdfea164736f6c6343000806000a", + Bin: "0x6101206040526001805463ffffffff60a01b1916609160a21b1790553480156200002857600080fd5b50604051620025ea380380620025ea8339810160408190526200004b91620002d8565b803380600081620000a35760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d657620000d6816200020f565b5050506001600160601b0319606091821b811660805284821b811660a05283821b811660c0529082901b1660e0526040805163288688f960e21b815290516000916001600160a01b0384169163a21a23e49160048082019260209290919082900301818787803b1580156200014a57600080fd5b505af11580156200015f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000185919062000322565b60c081901b6001600160c01b03191661010052604051631cd0704360e21b81526001600160401b03821660048201523060248201529091506001600160a01b03831690637341c10c90604401600060405180830381600087803b158015620001ec57600080fd5b505af115801562000201573d6000803e3d6000fd5b505050505050505062000354565b6001600160a01b0381163314156200026a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009a565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620002d357600080fd5b919050565b600080600060608486031215620002ee57600080fd5b620002f984620002bb565b92506200030960208501620002bb565b91506200031960408501620002bb565b90509250925092565b6000602082840312156200033557600080fd5b81516001600160401b03811681146200034d57600080fd5b9392505050565b60805160601c60a05160601c60c05160601c60e05160601c6101005160c01c612203620003e7600039600081816101970152610c5501526000818161028401528181610c1601528181610fec015281816110cd01526111680152600081816103fd015261161c01526000818161021b01528181610a6801526112ba01526000818161055801526105c001526122036000f3fe608060405234801561001057600080fd5b506004361061018d5760003560e01c80638da5cb5b116100e3578063c15ce4d71161008c578063f2fde38b11610066578063f2fde38b14610511578063f3fef3a314610524578063fc2a88c31461053757600080fd5b8063c15ce4d714610432578063c3f909d414610445578063cdd8d885146104d457600080fd5b8063a608a1e1116100bd578063a608a1e1146103e6578063ad178361146103f8578063bf17e5591461041f57600080fd5b80638da5cb5b146103ad578063a3907d71146103cb578063a4c0ed36146103d357600080fd5b80633b2bcbf11161014557806357a8070a1161011f57806357a8070a1461037557806379ba5097146103925780637fb5d19d1461039a57600080fd5b80633b2bcbf11461027f5780634306d354146102a657806348baa1c5146102c757600080fd5b80631b6b6d23116101765780631b6b6d23146102165780631fe543e3146102625780632f2770db1461027757600080fd5b8063030932bb14610192578063181f5a77146101d7575b600080fd5b6101b97f000000000000000000000000000000000000000000000000000000000000000081565b60405167ffffffffffffffff90911681526020015b60405180910390f35b604080518082018252601281527f56524656325772617070657220312e302e300000000000000000000000000000602082015290516101ce9190611f96565b61023d7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101ce565b610275610270366004611c7b565b610540565b005b610275610600565b61023d7f000000000000000000000000000000000000000000000000000000000000000081565b6102b96102b4366004611db4565b610636565b6040519081526020016101ce565b6103316102d5366004611c62565b600860205260009081526040902080546001820154600283015460039093015473ffffffffffffffffffffffffffffffffffffffff8316937401000000000000000000000000000000000000000090930463ffffffff16929085565b6040805173ffffffffffffffffffffffffffffffffffffffff909616865263ffffffff9094166020860152928401919091526060830152608082015260a0016101ce565b6003546103829060ff1681565b60405190151581526020016101ce565b61027561073d565b6102b96103a8366004611e1c565b61083a565b60005473ffffffffffffffffffffffffffffffffffffffff1661023d565b610275610940565b6102756103e1366004611b41565b610972565b60035461038290610100900460ff1681565b61023d7f000000000000000000000000000000000000000000000000000000000000000081565b61027561042d366004611db4565b610e50565b610275610440366004611ef0565b610ea7565b6004546005546006546007546040805194855263ffffffff80851660208701526401000000008504811691860191909152680100000000000000008404811660608601526c01000000000000000000000000840416608085015260ff700100000000000000000000000000000000909304831660a085015260c08401919091521660e0820152610100016101ce565b6001546104fc9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016101ce565b61027561051f366004611afc565b611252565b610275610532366004611b17565b611266565b6102b960025481565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146105f2576040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660248201526044015b60405180910390fd5b6105fc828261133b565b5050565b610608611546565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60035460009060ff166106a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e666967757265640000000000000060448201526064016105e9565b600354610100900460ff1615610717576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c65640000000000000000000000000060448201526064016105e9565b60006107216115c9565b90506107348363ffffffff163a8361173d565b9150505b919050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146107be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064016105e9565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60035460009060ff166108a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e666967757265640000000000000060448201526064016105e9565b600354610100900460ff161561091b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c65640000000000000000000000000060448201526064016105e9565b60006109256115c9565b90506109388463ffffffff16848361173d565b949350505050565b610948611546565b600380547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055565b60035460ff166109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e666967757265640000000000000060448201526064016105e9565b600354610100900460ff1615610a50576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c65640000000000000000000000000060448201526064016105e9565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610aef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b00000000000000000060448201526064016105e9565b60008080610aff84860186611dd1565b9250925092506000610b108461185e565b90506000610b1c6115c9565b90506000610b318663ffffffff163a8461173d565b905080891015610b9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f7700000000000000000000000000000000000000000060448201526064016105e9565b60075460ff1663ffffffff85161115610c12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f206869676800000000000000000000000000000060448201526064016105e9565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635d3b1d306006547f000000000000000000000000000000000000000000000000000000000000000089600560089054906101000a900463ffffffff16898d610c94919061206f565b610c9e919061206f565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e087901b168152600481019490945267ffffffffffffffff909216602484015261ffff16604483015263ffffffff90811660648301528816608482015260a401602060405180830381600087803b158015610d1d57600080fd5b505af1158015610d31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d559190611bea565b90506040518060a001604052808c73ffffffffffffffffffffffffffffffffffffffff1681526020018863ffffffff1681526020013a81526020018481526020018b8152506008600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff160217905550604082015181600101556060820151816002015560808201518160030155905050806002819055505050505050505050505050565b610e58611546565b6001805463ffffffff90921674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b610eaf611546565b6005805460ff808616700100000000000000000000000000000000027fffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff63ffffffff8981166c01000000000000000000000000027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff918c166801000000000000000002919091167fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff909516949094179390931792909216919091179091556006839055600780549183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00928316179055600380549091166001179055604080517fc3f909d4000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163c3f909d4916004828101926080929190829003018186803b15801561103257600080fd5b505afa158015611046573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106a9190611c03565b50600580547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790555050604080517f356dac7100000000000000000000000000000000000000000000000000000000815290517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169163356dac71916004808301926020929190829003018186803b15801561112857600080fd5b505afa15801561113c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111609190611bea565b6004819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635fbbc0d26040518163ffffffff1660e01b81526004016101206040518083038186803b1580156111cd57600080fd5b505afa1580156111e1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112059190611e3a565b50506005805463ffffffff909816640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff909816979097179096555050505050505050505050565b61125a611546565b6112638161187c565b50565b61126e611546565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8381166004830152602482018390527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb90604401602060405180830381600087803b1580156112fe57600080fd5b505af1158015611312573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113369190611bc8565b505050565b6000828152600860208181526040808420815160a081018352815473ffffffffffffffffffffffffffffffffffffffff808216835263ffffffff740100000000000000000000000000000000000000008304168387015260018401805495840195909552600284018054606085015260038501805460808601528b8a52979096527fffffffffffffffff000000000000000000000000000000000000000000000000909116909255918590559184905592909155815116611458576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e6400000000000000000000000000000060448201526064016105e9565b600080631fe543e360e01b8585604051602401611476929190612009565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060006114f0846020015163ffffffff16856000015184611972565b90508061153e57835160405173ffffffffffffffffffffffffffffffffffffffff9091169087907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146115c7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016105e9565b565b600554604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009263ffffffff161515918391829173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163feaf968c9160048082019260a092909190829003018186803b15801561166357600080fd5b505afa158015611677573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169b9190611f52565b5094509092508491505080156116c157506116b68242612130565b60055463ffffffff16105b156116cb57506004545b6000811215611736576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b207765692070726963650000000000000000000060448201526064016105e9565b9392505050565b600154600090819061176c9074010000000000000000000000000000000000000000900463ffffffff166119be565b60055463ffffffff6c01000000000000000000000000820481169161179f91680100000000000000009091041688612057565b6117a99190612057565b6117b390866120f3565b6117bd9190612057565b90506000836117d483670de0b6b3a76400006120f3565b6117de91906120bc565b60055490915060009060649061180b90700100000000000000000000000000000000900460ff1682612097565b6118189060ff16846120f3565b61182291906120bc565b60055490915060009061184890640100000000900463ffffffff1664e8d4a510006120f3565b6118529083612057565b98975050505050505050565b600061186b603f836120d0565b61187690600161206f565b92915050565b73ffffffffffffffffffffffffffffffffffffffff81163314156118fc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016105e9565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005a61138881101561198457600080fd5b61138881039050846040820482031161199c57600080fd5b50823b6119a857600080fd5b60008083516020850160008789f1949350505050565b6000466119ca81611a77565b15611a6e576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c06040518083038186803b158015611a1857600080fd5b505afa158015611a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a509190611d6a565b5050505091505083608c611a649190612057565b61093890826120f3565b50600092915050565b600061a4b1821480611a8b575062066eed82145b8061187657505062066eee1490565b803573ffffffffffffffffffffffffffffffffffffffff8116811461073857600080fd5b805162ffffff8116811461073857600080fd5b803560ff8116811461073857600080fd5b805169ffffffffffffffffffff8116811461073857600080fd5b600060208284031215611b0e57600080fd5b61173682611a9a565b60008060408385031215611b2a57600080fd5b611b3383611a9a565b946020939093013593505050565b60008060008060608587031215611b5757600080fd5b611b6085611a9a565b935060208501359250604085013567ffffffffffffffff80821115611b8457600080fd5b818701915087601f830112611b9857600080fd5b813581811115611ba757600080fd5b886020828501011115611bb957600080fd5b95989497505060200194505050565b600060208284031215611bda57600080fd5b8151801515811461173657600080fd5b600060208284031215611bfc57600080fd5b5051919050565b60008060008060808587031215611c1957600080fd5b8451611c24816121d4565b6020860151909450611c35816121e4565b6040860151909350611c46816121e4565b6060860151909250611c57816121e4565b939692955090935050565b600060208284031215611c7457600080fd5b5035919050565b60008060408385031215611c8e57600080fd5b8235915060208084013567ffffffffffffffff80821115611cae57600080fd5b818601915086601f830112611cc257600080fd5b813581811115611cd457611cd46121a5565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715611d1757611d176121a5565b604052828152858101935084860182860187018b1015611d3657600080fd5b600095505b83861015611d59578035855260019590950194938601938601611d3b565b508096505050505050509250929050565b60008060008060008060c08789031215611d8357600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b600060208284031215611dc657600080fd5b8135611736816121e4565b600080600060608486031215611de657600080fd5b8335611df1816121e4565b92506020840135611e01816121d4565b91506040840135611e11816121e4565b809150509250925092565b60008060408385031215611e2f57600080fd5b8235611b33816121e4565b60008060008060008060008060006101208a8c031215611e5957600080fd5b8951611e64816121e4565b60208b0151909950611e75816121e4565b60408b0151909850611e86816121e4565b60608b0151909750611e97816121e4565b60808b0151909650611ea8816121e4565b9450611eb660a08b01611abe565b9350611ec460c08b01611abe565b9250611ed260e08b01611abe565b9150611ee16101008b01611abe565b90509295985092959850929598565b600080600080600060a08688031215611f0857600080fd5b8535611f13816121e4565b94506020860135611f23816121e4565b9350611f3160408701611ad1565b925060608601359150611f4660808701611ad1565b90509295509295909350565b600080600080600060a08688031215611f6a57600080fd5b611f7386611ae2565b9450602086015193506040860151925060608601519150611f4660808701611ae2565b600060208083528351808285015260005b81811015611fc357858101830151858201604001528201611fa7565b81811115611fd5576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b6000604082018483526020604081850152818551808452606086019150828701935060005b8181101561204a5784518352938301939183019160010161202e565b5090979650505050505050565b6000821982111561206a5761206a612147565b500190565b600063ffffffff80831681851680830382111561208e5761208e612147565b01949350505050565b600060ff821660ff84168060ff038211156120b4576120b4612147565b019392505050565b6000826120cb576120cb612176565b500490565b600063ffffffff808416806120e7576120e7612176565b92169190910492915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561212b5761212b612147565b500290565b60008282101561214257612142612147565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61ffff8116811461126357600080fd5b63ffffffff8116811461126357600080fdfea164736f6c6343000806000a", } var VRFV2WrapperABI = VRFV2WrapperMetaData.ABI 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 694a9a6f41..2ad412a122 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\":[],\"name\":\"createSubscriptionAndFundNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"idx\",\"type\":\"uint256\"}],\"name\":\"getRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"randomWord\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_linkToken\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_recentRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"requester\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_subId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFMigratableCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinatorApiV1\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"setSubId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"topUpSubscriptionNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b50604051620019c6380380620019c68339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060038054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b6117b280620002146000396000f3fe6080604052600436106101445760003560e01c806380980043116100c0578063b96dbba711610074578063de367c8e11610059578063de367c8e146103c0578063eff27017146103ed578063f2fde38b1461040d57600080fd5b8063b96dbba714610398578063cf62c8ab146103a057600080fd5b80638ea98117116100a55780638ea98117146102c45780639eccacf6146102e4578063a168fa891461031157600080fd5b806380980043146102795780638da5cb5b1461029957600080fd5b806336bfffed11610117578063706da1ca116100fc578063706da1ca146101fc5780637725135b1461021257806379ba50971461026457600080fd5b806336bfffed146101c65780635d7d53e3146101e657600080fd5b80631d2b2afd146101495780631fe543e31461015357806329e5d831146101735780632fa4e442146101a6575b600080fd5b61015161042d565b005b34801561015f57600080fd5b5061015161016e3660046113eb565b610528565b34801561017f57600080fd5b5061019361018e36600461148f565b6105a9565b6040519081526020015b60405180910390f35b3480156101b257600080fd5b506101516101c136600461151c565b6106e6565b3480156101d257600080fd5b506101516101e13660046112f8565b610808565b3480156101f257600080fd5b5061019360045481565b34801561020857600080fd5b5061019360065481565b34801561021e57600080fd5b5060035461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019d565b34801561027057600080fd5b50610151610940565b34801561028557600080fd5b506101516102943660046113b9565b600655565b3480156102a557600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661023f565b3480156102d057600080fd5b506101516102df3660046112d6565b610a3d565b3480156102f057600080fd5b5060025461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561031d57600080fd5b5061036661032c3660046113b9565b6007602052600090815260409020805460019091015460ff821691610100900473ffffffffffffffffffffffffffffffffffffffff169083565b60408051931515845273ffffffffffffffffffffffffffffffffffffffff90921660208401529082015260600161019d565b610151610b48565b3480156103ac57600080fd5b506101516103bb36600461151c565b610bae565b3480156103cc57600080fd5b5060055461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103f957600080fd5b506101516104083660046114b1565b610bf5565b34801561041957600080fd5b506101516104283660046112d6565b610de0565b60065461049b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f742073657400000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6005546006546040517fe8509bff000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff9091169063e8509bff9034906024015b6000604051808303818588803b15801561050d57600080fd5b505af1158015610521573d6000803e3d6000fd5b5050505050565b60025473ffffffffffffffffffffffffffffffffffffffff16331461059b576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610492565b6105a58282610df4565b5050565b60008281526007602090815260408083208151608081018352815460ff811615158252610100900473ffffffffffffffffffffffffffffffffffffffff16818501526001820154818401526002820180548451818702810187019095528085528695929460608601939092919083018282801561064557602002820191906000526020600020905b815481526020019060010190808311610631575b50505050508152505090508060400151600014156106bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f72726563740000000000000000006044820152606401610492565b806060015183815181106106d5576106d5611739565b602002602001015191505092915050565b60065461074f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f74207365740000000000000000000000000000000000000000006044820152606401610492565b60035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b81526004016107b6939291906115b5565b602060405180830381600087803b1580156107d057600080fd5b505af11580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a5919061139c565b600654610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f7420736574000000000000000000000000000000000000006044820152606401610492565b60005b81518110156105a557600554600654835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c91908590859081106108b7576108b7611739565b60200260200101516040518363ffffffff1660e01b81526004016108fb92919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561091557600080fd5b505af1158015610929573d6000803e3d6000fd5b505050508080610938906116d9565b915050610874565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610492565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610a7d575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610b015733610aa260005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610492565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b50610ebf565b506005546006546040517fe8509bff000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff9091169063e8509bff9034906024016104f4565b610bb6610ebf565b5060035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea0931691859101610789565b60006040518060c0016040528084815260200160065481526020018661ffff1681526020018763ffffffff1681526020018563ffffffff168152602001610c4b6040518060200160405280861515815250611004565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610ca9908590600401611601565b602060405180830381600087803b158015610cc357600080fd5b505af1158015610cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfb91906113d2565b604080516080810182526000808252336020808401918252838501868152855184815280830187526060860190815287855260078352959093208451815493517fffffffffffffffffffffff0000000000000000000000000000000000000000009094169015157fffffffffffffffffffffff0000000000000000000000000000000000000000ff161761010073ffffffffffffffffffffffffffffffffffffffff9094169390930292909217825591516001820155925180519495509193849392610dce926002850192910190611239565b50505060049190915550505050505050565b610de86110c0565b610df181611143565b50565b6004548214610e5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f72726563740000000000000000006044820152606401610492565b60008281526007602090815260409091208251610e8492600290920191840190611239565b5050600090815260076020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600060065460001415610ffd57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610f3657600080fd5b505af1158015610f4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6e91906113d2565b60068190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b158015610fe457600080fd5b505af1158015610ff8573d6000803e3d6000fd5b505050505b5060065490565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161103d91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611141576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610492565b565b73ffffffffffffffffffffffffffffffffffffffff81163314156111c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610492565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215611274579160200282015b82811115611274578251825591602001919060010190611259565b50611280929150611284565b5090565b5b808211156112805760008155600101611285565b803573ffffffffffffffffffffffffffffffffffffffff811681146112bd57600080fd5b919050565b803563ffffffff811681146112bd57600080fd5b6000602082840312156112e857600080fd5b6112f182611299565b9392505050565b6000602080838503121561130b57600080fd5b823567ffffffffffffffff81111561132257600080fd5b8301601f8101851361133357600080fd5b8035611346611341826116b5565b611666565b80828252848201915084840188868560051b870101111561136657600080fd5b600094505b838510156113905761137c81611299565b83526001949094019391850191850161136b565b50979650505050505050565b6000602082840312156113ae57600080fd5b81516112f181611797565b6000602082840312156113cb57600080fd5b5035919050565b6000602082840312156113e457600080fd5b5051919050565b600080604083850312156113fe57600080fd5b8235915060208084013567ffffffffffffffff81111561141d57600080fd5b8401601f8101861361142e57600080fd5b803561143c611341826116b5565b80828252848201915084840189868560051b870101111561145c57600080fd5b600094505b8385101561147f578035835260019490940193918501918501611461565b5080955050505050509250929050565b600080604083850312156114a257600080fd5b50508035926020909101359150565b600080600080600060a086880312156114c957600080fd5b6114d2866112c2565b9450602086013561ffff811681146114e957600080fd5b93506114f7604087016112c2565b925060608601359150608086013561150e81611797565b809150509295509295909350565b60006020828403121561152e57600080fd5b81356bffffffffffffffffffffffff811681146112f157600080fd5b6000815180845260005b8181101561157057602081850181015186830182015201611554565b81811115611582576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006115f8606083018461154a565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261165e60e084018261154a565b949350505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156116ad576116ad611768565b604052919050565b600067ffffffffffffffff8211156116cf576116cf611768565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611732577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8015158114610df157600080fdfea164736f6c6343000806000a", + 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_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinatorApiV1\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"setSubId\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"topUpSubscriptionNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b50604051620019c6380380620019c68339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060038054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b6117b280620002146000396000f3fe6080604052600436106101445760003560e01c806380980043116100c0578063b96dbba711610074578063de367c8e11610059578063de367c8e146103c0578063eff27017146103ed578063f2fde38b1461040d57600080fd5b8063b96dbba714610398578063cf62c8ab146103a057600080fd5b80638ea98117116100a55780638ea98117146102c45780639eccacf6146102e4578063a168fa891461031157600080fd5b806380980043146102795780638da5cb5b1461029957600080fd5b806336bfffed11610117578063706da1ca116100fc578063706da1ca146101fc5780637725135b1461021257806379ba50971461026457600080fd5b806336bfffed146101c65780635d7d53e3146101e657600080fd5b80631d2b2afd146101495780631fe543e31461015357806329e5d831146101735780632fa4e442146101a6575b600080fd5b61015161042d565b005b34801561015f57600080fd5b5061015161016e3660046113eb565b610528565b34801561017f57600080fd5b5061019361018e36600461148f565b6105a9565b6040519081526020015b60405180910390f35b3480156101b257600080fd5b506101516101c136600461151c565b6106e6565b3480156101d257600080fd5b506101516101e13660046112f8565b610808565b3480156101f257600080fd5b5061019360045481565b34801561020857600080fd5b5061019360065481565b34801561021e57600080fd5b5060035461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161019d565b34801561027057600080fd5b50610151610940565b34801561028557600080fd5b506101516102943660046113b9565b600655565b3480156102a557600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661023f565b3480156102d057600080fd5b506101516102df3660046112d6565b610a3d565b3480156102f057600080fd5b5060025461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561031d57600080fd5b5061036661032c3660046113b9565b6007602052600090815260409020805460019091015460ff821691610100900473ffffffffffffffffffffffffffffffffffffffff169083565b60408051931515845273ffffffffffffffffffffffffffffffffffffffff90921660208401529082015260600161019d565b610151610b48565b3480156103ac57600080fd5b506101516103bb36600461151c565b610bae565b3480156103cc57600080fd5b5060055461023f9073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103f957600080fd5b506101516104083660046114b1565b610bf5565b34801561041957600080fd5b506101516104283660046112d6565b610de0565b60065461049b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f742073657400000000000000000000000000000000000000000060448201526064015b60405180910390fd5b6005546006546040517f95b55cfc000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff909116906395b55cfc9034906024015b6000604051808303818588803b15801561050d57600080fd5b505af1158015610521573d6000803e3d6000fd5b5050505050565b60025473ffffffffffffffffffffffffffffffffffffffff16331461059b576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610492565b6105a58282610df4565b5050565b60008281526007602090815260408083208151608081018352815460ff811615158252610100900473ffffffffffffffffffffffffffffffffffffffff16818501526001820154818401526002820180548451818702810187019095528085528695929460608601939092919083018282801561064557602002820191906000526020600020905b815481526020019060010190808311610631575b50505050508152505090508060400151600014156106bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f72726563740000000000000000006044820152606401610492565b806060015183815181106106d5576106d5611739565b602002602001015191505092915050565b60065461074f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f74207365740000000000000000000000000000000000000000006044820152606401610492565b60035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b81526004016107b6939291906115b5565b602060405180830381600087803b1580156107d057600080fd5b505af11580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105a5919061139c565b600654610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f7420736574000000000000000000000000000000000000006044820152606401610492565b60005b81518110156105a557600554600654835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c91908590859081106108b7576108b7611739565b60200260200101516040518363ffffffff1660e01b81526004016108fb92919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b15801561091557600080fd5b505af1158015610929573d6000803e3d6000fd5b505050508080610938906116d9565b915050610874565b60015473ffffffffffffffffffffffffffffffffffffffff1633146109c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610492565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610a7d575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610b015733610aa260005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610492565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b610b50610ebf565b506005546006546040517f95b55cfc000000000000000000000000000000000000000000000000000000008152600481019190915273ffffffffffffffffffffffffffffffffffffffff909116906395b55cfc9034906024016104f4565b610bb6610ebf565b5060035460025460065460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea0931691859101610789565b60006040518060c0016040528084815260200160065481526020018661ffff1681526020018763ffffffff1681526020018563ffffffff168152602001610c4b6040518060200160405280861515815250611004565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610ca9908590600401611601565b602060405180830381600087803b158015610cc357600080fd5b505af1158015610cd7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cfb91906113d2565b604080516080810182526000808252336020808401918252838501868152855184815280830187526060860190815287855260078352959093208451815493517fffffffffffffffffffffff0000000000000000000000000000000000000000009094169015157fffffffffffffffffffffff0000000000000000000000000000000000000000ff161761010073ffffffffffffffffffffffffffffffffffffffff9094169390930292909217825591516001820155925180519495509193849392610dce926002850192910190611239565b50505060049190915550505050505050565b610de86110c0565b610df181611143565b50565b6004548214610e5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f7265717565737420494420697320696e636f72726563740000000000000000006044820152606401610492565b60008281526007602090815260409091208251610e8492600290920191840190611239565b5050600090815260076020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b600060065460001415610ffd57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610f3657600080fd5b505af1158015610f4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6e91906113d2565b60068190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b158015610fe457600080fd5b505af1158015610ff8573d6000803e3d6000fd5b505050505b5060065490565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161103d91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314611141576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610492565b565b73ffffffffffffffffffffffffffffffffffffffff81163314156111c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610492565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b828054828255906000526020600020908101928215611274579160200282015b82811115611274578251825591602001919060010190611259565b50611280929150611284565b5090565b5b808211156112805760008155600101611285565b803573ffffffffffffffffffffffffffffffffffffffff811681146112bd57600080fd5b919050565b803563ffffffff811681146112bd57600080fd5b6000602082840312156112e857600080fd5b6112f182611299565b9392505050565b6000602080838503121561130b57600080fd5b823567ffffffffffffffff81111561132257600080fd5b8301601f8101851361133357600080fd5b8035611346611341826116b5565b611666565b80828252848201915084840188868560051b870101111561136657600080fd5b600094505b838510156113905761137c81611299565b83526001949094019391850191850161136b565b50979650505050505050565b6000602082840312156113ae57600080fd5b81516112f181611797565b6000602082840312156113cb57600080fd5b5035919050565b6000602082840312156113e457600080fd5b5051919050565b600080604083850312156113fe57600080fd5b8235915060208084013567ffffffffffffffff81111561141d57600080fd5b8401601f8101861361142e57600080fd5b803561143c611341826116b5565b80828252848201915084840189868560051b870101111561145c57600080fd5b600094505b8385101561147f578035835260019490940193918501918501611461565b5080955050505050509250929050565b600080604083850312156114a257600080fd5b50508035926020909101359150565b600080600080600060a086880312156114c957600080fd5b6114d2866112c2565b9450602086013561ffff811681146114e957600080fd5b93506114f7604087016112c2565b925060608601359150608086013561150e81611797565b809150509295509295909350565b60006020828403121561152e57600080fd5b81356bffffffffffffffffffffffff811681146112f157600080fd5b6000815180845260005b8181101561157057602081850181015186830182015201611554565b81811115611582576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff831660208201526060604082015260006115f8606083018461154a565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261165e60e084018261154a565b949350505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156116ad576116ad611768565b604052919050565b600067ffffffffffffffff8211156116cf576116cf611768565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611732577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b8015158114610df157600080fdfea164736f6c6343000806000a", } var VRFV2PlusConsumerExampleABI = VRFV2PlusConsumerExampleMetaData.ABI diff --git a/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go b/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go index 413f3e52b2..d5a58fa0f9 100644 --- a/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go +++ b/core/gethwrappers/generated/vrfv2plus_reverting_example/vrfv2plus_reverting_example.go @@ -31,7 +31,7 @@ var ( ) var VRFV2PlusRevertingExampleMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"vrfCoordinator\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"createSubscriptionAndFund\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"minReqConfs\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"}],\"name\":\"requestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_subId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFMigratableCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + 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\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"minReqConfs\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"}],\"name\":\"requestRandomness\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_gasAvailable\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_randomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_subId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint96\",\"name\":\"amount\",\"type\":\"uint96\"}],\"name\":\"topUpSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"name\":\"updateSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", Bin: "0x60806040523480156200001157600080fd5b506040516200121f3803806200121f8339810160408190526200003491620001cc565b8133806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf8162000103565b5050600280546001600160a01b03199081166001600160a01b0394851617909155600580548216958416959095179094555060068054909316911617905562000204565b6001600160a01b0381163314156200015e5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b0381168114620001c757600080fd5b919050565b60008060408385031215620001e057600080fd5b620001eb83620001af565b9150620001fb60208401620001af565b90509250929050565b61100b80620002146000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80638ea981171161008c578063e89e106a11610066578063e89e106a146101e6578063f08c5daa146101ef578063f2fde38b146101f8578063f6eaffc81461020b57600080fd5b80638ea98117146101a05780639eccacf6146101b3578063cf62c8ab146101d357600080fd5b806336bfffed116100c857806336bfffed1461013d578063706da1ca1461015057806379ba5097146101595780638da5cb5b1461016157600080fd5b80631fe543e3146100ef5780632e75964e146101045780632fa4e4421461012a575b600080fd5b6101026100fd366004610cdf565b61021e565b005b610117610112366004610c4d565b6102a4565b6040519081526020015b60405180910390f35b610102610138366004610d83565b6103a1565b61010261014b366004610b87565b6104c3565b61011760075481565b6101026105fb565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610121565b6101026101ae366004610b65565b6106f8565b60025461017b9073ffffffffffffffffffffffffffffffffffffffff1681565b6101026101e1366004610d83565b610803565b61011760045481565b61011760085481565b610102610206366004610b65565b61097a565b610117610219366004610cad565b61098e565b60025473ffffffffffffffffffffffffffffffffffffffff163314610296576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6102a08282600080fd5b5050565b6040805160c081018252868152602080820187905261ffff86168284015263ffffffff80861660608401528416608083015282519081018352600080825260a083019190915260055492517f9b1c385e000000000000000000000000000000000000000000000000000000008152909273ffffffffffffffffffffffffffffffffffffffff1690639b1c385e9061033f908490600401610e68565b602060405180830381600087803b15801561035957600080fd5b505af115801561036d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103919190610cc6565b6004819055979650505050505050565b60075461040a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f737562206e6f7420736574000000000000000000000000000000000000000000604482015260640161028d565b60065460055460075460408051602081019290925273ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591015b6040516020818303038152906040526040518463ffffffff1660e01b815260040161047193929190610e1c565b602060405180830381600087803b15801561048b57600080fd5b505af115801561049f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102a09190610c2b565b60075461052c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600d60248201527f7375624944206e6f742073657400000000000000000000000000000000000000604482015260640161028d565b60005b81518110156102a057600554600754835173ffffffffffffffffffffffffffffffffffffffff9092169163bec4c08c919085908590811061057257610572610fa0565b60200260200101516040518363ffffffff1660e01b81526004016105b692919091825273ffffffffffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b1580156105d057600080fd5b505af11580156105e4573d6000803e3d6000fd5b5050505080806105f390610f40565b91505061052f565b60015473ffffffffffffffffffffffffffffffffffffffff16331461067c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161028d565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610738575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156107bc573361075d60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161028d565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60075461040a57600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561087457600080fd5b505af1158015610888573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ac9190610cc6565b60078190556005546040517fbec4c08c000000000000000000000000000000000000000000000000000000008152600481019290925230602483015273ffffffffffffffffffffffffffffffffffffffff169063bec4c08c90604401600060405180830381600087803b15801561092257600080fd5b505af1158015610936573d6000803e3d6000fd5b5050505060065460055460075460405173ffffffffffffffffffffffffffffffffffffffff93841693634000aea09316918591610444919060200190815260200190565b6109826109af565b61098b81610a32565b50565b6003818154811061099e57600080fd5b600091825260209091200154905081565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161028d565b565b73ffffffffffffffffffffffffffffffffffffffff8116331415610ab2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161028d565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b4c57600080fd5b919050565b803563ffffffff81168114610b4c57600080fd5b600060208284031215610b7757600080fd5b610b8082610b28565b9392505050565b60006020808385031215610b9a57600080fd5b823567ffffffffffffffff811115610bb157600080fd5b8301601f81018513610bc257600080fd5b8035610bd5610bd082610f1c565b610ecd565b80828252848201915084840188868560051b8701011115610bf557600080fd5b600094505b83851015610c1f57610c0b81610b28565b835260019490940193918501918501610bfa565b50979650505050505050565b600060208284031215610c3d57600080fd5b81518015158114610b8057600080fd5b600080600080600060a08688031215610c6557600080fd5b8535945060208601359350604086013561ffff81168114610c8557600080fd5b9250610c9360608701610b51565b9150610ca160808701610b51565b90509295509295909350565b600060208284031215610cbf57600080fd5b5035919050565b600060208284031215610cd857600080fd5b5051919050565b60008060408385031215610cf257600080fd5b8235915060208084013567ffffffffffffffff811115610d1157600080fd5b8401601f81018613610d2257600080fd5b8035610d30610bd082610f1c565b80828252848201915084840189868560051b8701011115610d5057600080fd5b600094505b83851015610d73578035835260019490940193918501918501610d55565b5080955050505050509250929050565b600060208284031215610d9557600080fd5b81356bffffffffffffffffffffffff81168114610b8057600080fd5b6000815180845260005b81811015610dd757602081850181015186830182015201610dbb565b81811115610de9576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff841681526bffffffffffffffffffffffff83166020820152606060408201526000610e5f6060830184610db1565b95945050505050565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c080840152610ec560e0840182610db1565b949350505050565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715610f1457610f14610fcf565b604052919050565b600067ffffffffffffffff821115610f3657610f36610fcf565b5060051b60200190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610f99577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } diff --git a/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go b/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go index 26f471725c..2dcb243946 100644 --- a/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go +++ b/core/gethwrappers/generated/vrfv2plus_wrapper/vrfv2plus_wrapper.go @@ -31,15 +31,15 @@ var ( ) var VRFV2PlusWrapperMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkEthFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"WrapperFulfillmentFailed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"COORDINATOR\",\"outputs\":[{\"internalType\":\"contractExtendedVRFCoordinatorV2PlusInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SUBSCRIPTION_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"enable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"maxNumWords\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"requestRandomWordsInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_callbacks\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"requestGasPrice\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_configured\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_disabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fulfillmentTxSizeBytes\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_link\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_linkEthFeed\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFMigratableCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"_wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"_maxNumWords\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"size\",\"type\":\"uint32\"}],\"name\":\"setFulfillmentTxSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"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\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60c06040526004805463ffffffff60a01b1916609160a21b1790553480156200002757600080fd5b50604051620030e7380380620030e78339810160408190526200004a9162000317565b803380600081620000a25760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d557620000d5816200024e565b5050600280546001600160a01b0319166001600160a01b03938416179055508316156200011857600380546001600160a01b0319166001600160a01b0385161790555b6001600160a01b038216156200014457600480546001600160a01b0319166001600160a01b0384161790555b806001600160a01b03166080816001600160a01b031660601b815250506000816001600160a01b031663a21a23e46040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156200019f57600080fd5b505af1158015620001b4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001da919062000361565b60a0819052604051632fb1302360e21b8152600481018290523060248201529091506001600160a01b0383169063bec4c08c90604401600060405180830381600087803b1580156200022b57600080fd5b505af115801562000240573d6000803e3d6000fd5b50505050505050506200037b565b6001600160a01b038116331415620002a95760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000099565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200031257600080fd5b919050565b6000806000606084860312156200032d57600080fd5b6200033884620002fa565b92506200034860208501620002fa565b91506200035860408501620002fa565b90509250925092565b6000602082840312156200037457600080fd5b5051919050565b60805160601c60a051612d12620003d5600039600081816101ef01528181610d2301526115e40152600081816102f901528181610ded0152818161166b0152818161197301528181611a540152611aef0152612d126000f3fe6080604052600436106101d85760003560e01c80638da5cb5b11610102578063bf17e55911610095578063da4f5e6d11610064578063da4f5e6d146106ff578063f2fde38b1461072c578063f3fef3a31461074c578063fc2a88c31461076c57600080fd5b8063bf17e559146105cd578063c15ce4d7146105ed578063c3f909d41461060d578063cdd8d885146106b557600080fd5b8063a02e0616116100d1578063a02e061614610559578063a3907d7114610579578063a4c0ed361461058e578063a608a1e1146105ae57600080fd5b80638da5cb5b146104c15780638ea98117146104ec578063981837d51461050c5780639eccacf61461052c57600080fd5b80634306d3541161017a57806361d386661161014957806361d386661461044c57806362a504fc1461047957806379ba50971461048c5780637fb5d19d146104a157600080fd5b80634306d3541461034057806348baa1c5146103605780634b1609351461040257806357a8070a1461042257600080fd5b80631fe543e3116101b65780631fe543e3146102925780632f2770db146102b25780633255c456146102c75780633b2bcbf1146102e757600080fd5b8063030932bb146101dd57806307b18bde14610224578063181f5a7714610246575b600080fd5b3480156101e957600080fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561023057600080fd5b5061024461023f36600461263a565b610782565b005b34801561025257600080fd5b50604080518082018252601281527f56524656325772617070657220312e302e3000000000000000000000000000006020820152905161021b9190612aa8565b34801561029e57600080fd5b506102446102ad36600461279e565b61085e565b3480156102be57600080fd5b506102446108df565b3480156102d357600080fd5b506102116102e236600461293f565b610915565b3480156102f357600080fd5b5061031b7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161021b565b34801561034c57600080fd5b5061021161035b3660046128d7565b610a0d565b34801561036c57600080fd5b506103cb61037b366004612785565b600b602052600090815260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff82169174010000000000000000000000000000000000000000900463ffffffff169083565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff90921660208401529082015260600161021b565b34801561040e57600080fd5b5061021161041d3660046128d7565b610b14565b34801561042e57600080fd5b5060065461043c9060ff1681565b604051901515815260200161021b565b34801561045857600080fd5b5060045461031b9073ffffffffffffffffffffffffffffffffffffffff1681565b6102116104873660046128f4565b610c0b565b34801561049857600080fd5b50610244610f1d565b3480156104ad57600080fd5b506102116104bc36600461293f565b61101a565b3480156104cd57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff1661031b565b3480156104f857600080fd5b5061024461050736600461261f565b611120565b34801561051857600080fd5b5061024461052736600461261f565b61122b565b34801561053857600080fd5b5060025461031b9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561056557600080fd5b5061024461057436600461261f565b61127a565b34801561058557600080fd5b50610244611319565b34801561059a57600080fd5b506102446105a9366004612664565b61134b565b3480156105ba57600080fd5b5060065461043c90610100900460ff1681565b3480156105d957600080fd5b506102446105e83660046128d7565b6117cb565b3480156105f957600080fd5b50610244610608366004612997565b611822565b34801561061957600080fd5b50600754600854600954600a546040805194855263ffffffff808516602087015264010000000085048116918601919091526c01000000000000000000000000840481166060860152700100000000000000000000000000000000840416608085015260ff74010000000000000000000000000000000000000000909304831660a085015260c08401919091521660e08201526101000161021b565b3480156106c157600080fd5b506004546106ea9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161021b565b34801561070b57600080fd5b5060035461031b9073ffffffffffffffffffffffffffffffffffffffff1681565b34801561073857600080fd5b5061024461074736600461261f565b611bfe565b34801561075857600080fd5b5061024461076736600461263a565b611c12565b34801561077857600080fd5b5061021160055481565b61078a611cfc565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146107e4576040519150601f19603f3d011682016040523d82523d6000602084013e6107e9565b606091505b5050905080610859576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6661696c656420746f207769746864726177206e61746976650000000000000060448201526064015b60405180910390fd5b505050565b60025473ffffffffffffffffffffffffffffffffffffffff1633146108d1576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610850565b6108db8282611d7f565b5050565b6108e7611cfc565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60065460009060ff16610984576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff16156109f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b610a068363ffffffff1683611f6b565b9392505050565b60065460009060ff16610a7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff1615610aee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b6000610af861207c565b9050610b0b8363ffffffff163a836121cb565b9150505b919050565b60065460009060ff16610b83576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff1615610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b610c058263ffffffff163a611f6b565b92915050565b600080610c17856122f8565b90506000610c2b8663ffffffff163a611f6b565b905080341015610c97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610850565b600a5460ff1663ffffffff85161115610d0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610850565b60006040518060c0016040528060095481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018761ffff1681526020016008600c9054906101000a900463ffffffff16858a610d709190612b7e565b610d7a9190612b7e565b63ffffffff1681526020018663ffffffff168152602001610dab604051806020016040528060011515815250612310565b90526040517f9b1c385e00000000000000000000000000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690639b1c385e90610e22908490600401612abb565b602060405180830381600087803b158015610e3c57600080fd5b505af1158015610e50573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e74919061270d565b6040805160608101825233815263ffffffff808b1660208084019182523a8486019081526000878152600b90925294902092518354915190921674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff9290921691909117178155905160019091015593505050509392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f9e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610850565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60065460009060ff16611089576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff16156110fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b600061110561207c565b90506111188463ffffffff1684836121cb565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590611160575060025473ffffffffffffffffffffffffffffffffffffffff163314155b156111e4573361118560005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610850565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611233611cfc565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611282611cfc565b60035473ffffffffffffffffffffffffffffffffffffffff16156112d2576040517f2d118a6e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b611321611cfc565b600680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055565b60065460ff166113b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610850565b600654610100900460ff1615611429576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610850565b60035473ffffffffffffffffffffffffffffffffffffffff1633146114aa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b0000000000000000006044820152606401610850565b600080806114ba848601866128f4565b92509250925060006114cb846122f8565b905060006114d761207c565b905060006114ec8663ffffffff163a846121cb565b905080891015611558576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610850565b600a5460ff1663ffffffff851611156115cd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610850565b60006040518060c0016040528060095481526020017f000000000000000000000000000000000000000000000000000000000000000081526020018761ffff1681526020016008600c9054906101000a900463ffffffff16868a6116319190612b7e565b61163b9190612b7e565b63ffffffff1681526020018663ffffffff16815260200160405180602001604052806000815250815250905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16639b1c385e836040518263ffffffff1660e01b81526004016116c29190612abb565b602060405180830381600087803b1580156116dc57600080fd5b505af11580156116f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611714919061270d565b6040805160608101825273ffffffffffffffffffffffffffffffffffffffff9e8f16815263ffffffff9a8b1660208083019182523a8385019081526000868152600b909252939020915182549151909c1674010000000000000000000000000000000000000000027fffffffffffffffff0000000000000000000000000000000000000000000000009091169b909f169a909a179d909d1789559b5160019098019790975550505060059790975550505050505050565b6117d3611cfc565b6004805463ffffffff90921674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b61182a611cfc565b6008805460ff80861674010000000000000000000000000000000000000000027fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff63ffffffff898116700100000000000000000000000000000000027fffffffffffffffffffffffff00000000ffffffffffffffffffffffffffffffff918c166c0100000000000000000000000002919091167fffffffffffffffffffffffff0000000000000000ffffffffffffffffffffffff909516949094179390931792909216919091179091556009839055600a80549183167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00928316179055600680549091166001179055604080517f088070f5000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169163088070f5916004828101926080929190829003018186803b1580156119b957600080fd5b505afa1580156119cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119f19190612726565b50600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff929092169190911790555050604080517f043bd6ae00000000000000000000000000000000000000000000000000000000815290517f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169163043bd6ae916004808301926020929190829003018186803b158015611aaf57600080fd5b505afa158015611ac3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ae7919061270d565b6007819055507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636b6feccc6040518163ffffffff1660e01b8152600401604080518083038186803b158015611b5257600080fd5b505afa158015611b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8a919061295d565b600880547fffffffffffffffffffffffffffffffffffffffff0000000000000000ffffffff166801000000000000000063ffffffff938416027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff161764010000000093909216929092021790555050505050565b611c06611cfc565b611c0f816123cc565b50565b611c1a611cfc565b6003546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490529091169063a9059cbb90604401602060405180830381600087803b158015611c8e57600080fd5b505af1158015611ca2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc691906126eb565b6108db576040517f7c07fc4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314611d7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610850565b565b6000828152600b602081815260408084208151606081018352815473ffffffffffffffffffffffffffffffffffffffff808216835263ffffffff740100000000000000000000000000000000000000008304168387015260018401805495840195909552898852959094527fffffffffffffffff000000000000000000000000000000000000000000000000909316905592909255815116611e7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610850565b600080631fe543e360e01b8585604051602401611e9b929190612b18565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000611f15846020015163ffffffff168560000151846124c2565b905080611f6357835160405173ffffffffffffffffffffffffffffffffffffffff9091169087907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b505050505050565b6004546000908190611f9a9074010000000000000000000000000000000000000000900463ffffffff1661250e565b60085463ffffffff7001000000000000000000000000000000008204811691611fd5916c010000000000000000000000009091041687612b66565b611fdf9190612b66565b611fe99085612c02565b611ff39190612b66565b60085490915081906000906064906120269074010000000000000000000000000000000000000000900460ff1682612ba6565b6120339060ff1684612c02565b61203d9190612bcb565b6008549091506000906120679068010000000000000000900463ffffffff1664e8d4a51000612c02565b6120719083612b66565b979650505050505050565b60085460048054604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009463ffffffff161515938593849373ffffffffffffffffffffffffffffffffffffffff9091169263feaf968c928281019260a0929190829003018186803b1580156120f857600080fd5b505afa15801561210c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061213091906129f9565b509450909250849150508015612156575061214b8242612c3f565b60085463ffffffff16105b1561216057506007545b6000811215610a06576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b20776569207072696365000000000000000000006044820152606401610850565b60045460009081906121fa9074010000000000000000000000000000000000000000900463ffffffff1661250e565b60085463ffffffff7001000000000000000000000000000000008204811691612235916c010000000000000000000000009091041688612b66565b61223f9190612b66565b6122499086612c02565b6122539190612b66565b905060008361226a83670de0b6b3a7640000612c02565b6122749190612bcb565b6008549091506000906064906122a59074010000000000000000000000000000000000000000900460ff1682612ba6565b6122b29060ff1684612c02565b6122bc9190612bcb565b6008549091506000906122e290640100000000900463ffffffff1664e8d4a51000612c02565b6122ec9083612b66565b98975050505050505050565b6000612305603f83612bdf565b610c05906001612b7e565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161234991511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b73ffffffffffffffffffffffffffffffffffffffff811633141561244c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610850565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005a6113888110156124d457600080fd5b6113888103905084604082048203116124ec57600080fd5b50823b6124f857600080fd5b60008083516020850160008789f1949350505050565b60004661a4b1811480612523575062066eed81145b156125c7576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c06040518083038186803b15801561257157600080fd5b505afa158015612585573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125a9919061288d565b5050505091505083608c6125bd9190612b66565b6111189082612c02565b50600092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b0f57600080fd5b803560ff81168114610b0f57600080fd5b805169ffffffffffffffffffff81168114610b0f57600080fd5b60006020828403121561263157600080fd5b610a06826125d0565b6000806040838503121561264d57600080fd5b612656836125d0565b946020939093013593505050565b6000806000806060858703121561267a57600080fd5b612683856125d0565b935060208501359250604085013567ffffffffffffffff808211156126a757600080fd5b818701915087601f8301126126bb57600080fd5b8135818111156126ca57600080fd5b8860208285010111156126dc57600080fd5b95989497505060200194505050565b6000602082840312156126fd57600080fd5b81518015158114610a0657600080fd5b60006020828403121561271f57600080fd5b5051919050565b6000806000806080858703121561273c57600080fd5b845161274781612ce3565b602086015190945061275881612cf3565b604086015190935061276981612cf3565b606086015190925061277a81612cf3565b939692955090935050565b60006020828403121561279757600080fd5b5035919050565b600080604083850312156127b157600080fd5b8235915060208084013567ffffffffffffffff808211156127d157600080fd5b818601915086601f8301126127e557600080fd5b8135818111156127f7576127f7612cb4565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561283a5761283a612cb4565b604052828152858101935084860182860187018b101561285957600080fd5b600095505b8386101561287c57803585526001959095019493860193860161285e565b508096505050505050509250929050565b60008060008060008060c087890312156128a657600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b6000602082840312156128e957600080fd5b8135610a0681612cf3565b60008060006060848603121561290957600080fd5b833561291481612cf3565b9250602084013561292481612ce3565b9150604084013561293481612cf3565b809150509250925092565b6000806040838503121561295257600080fd5b823561265681612cf3565b6000806040838503121561297057600080fd5b825161297b81612cf3565b602084015190925061298c81612cf3565b809150509250929050565b600080600080600060a086880312156129af57600080fd5b85356129ba81612cf3565b945060208601356129ca81612cf3565b93506129d8604087016125f4565b9250606086013591506129ed608087016125f4565b90509295509295909350565b600080600080600060a08688031215612a1157600080fd5b612a1a86612605565b94506020860151935060408601519250606086015191506129ed60808701612605565b6000815180845260005b81811015612a6357602081850181015186830182015201612a47565b81811115612a75576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a066020830184612a3d565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261111860e0840182612a3d565b6000604082018483526020604081850152818551808452606086019150828701935060005b81811015612b5957845183529383019391830191600101612b3d565b5090979650505050505050565b60008219821115612b7957612b79612c56565b500190565b600063ffffffff808316818516808303821115612b9d57612b9d612c56565b01949350505050565b600060ff821660ff84168060ff03821115612bc357612bc3612c56565b019392505050565b600082612bda57612bda612c85565b500490565b600063ffffffff80841680612bf657612bf6612c85565b92169190910492915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612c3a57612c3a612c56565b500290565b600082821015612c5157612c51612c56565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61ffff81168114611c0f57600080fd5b63ffffffff81168114611c0f57600080fdfea164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_linkNativeFeed\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_coordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"WrapperFulfillmentFailed\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"SUBSCRIPTION_ID\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"}],\"name\":\"calculateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"disable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"enable\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"_requestGasPriceWei\",\"type\":\"uint256\"}],\"name\":\"estimateRequestPriceNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getConfig\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"maxNumWords\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_sender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"_data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"}],\"name\":\"requestRandomWordsInNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_callbacks\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"callbackAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"requestGasPrice\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_configured\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_disabled\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fulfillmentTxSizeBytes\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_link\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_linkNativeFeed\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_wrapperGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"_coordinatorGasOverhead\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"_wrapperPremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint8\",\"name\":\"_maxNumWords\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"size\",\"type\":\"uint32\"}],\"name\":\"setFulfillmentTxSize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"}],\"name\":\"setLINK\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLinkNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"typeAndVersion\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040526007805463ffffffff60201b1916650244000000001790553480156200002957600080fd5b5060405162002df438038062002df48339810160408190526200004c9162000323565b803380600081620000a45760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000d757620000d7816200025a565b5050600280546001600160a01b0319166001600160a01b03938416179055508316156200012857600680546001600160601b03166c010000000000000000000000006001600160a01b038616021790555b6001600160a01b038216156200016257600780546001600160601b03166c010000000000000000000000006001600160a01b038516021790555b6002546040805163288688f960e21b815290516000926001600160a01b03169163a21a23e491600480830192602092919082900301818787803b158015620001a957600080fd5b505af1158015620001be573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001e491906200036d565b6080819052600254604051632fb1302360e21b8152600481018390523060248201529192506001600160a01b03169063bec4c08c90604401600060405180830381600087803b1580156200023757600080fd5b505af11580156200024c573d6000803e3d6000fd5b505050505050505062000387565b6001600160a01b038116331415620002b55760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016200009b565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b80516001600160a01b03811681146200031e57600080fd5b919050565b6000806000606084860312156200033957600080fd5b620003448462000306565b9250620003546020850162000306565b9150620003646040850162000306565b90509250925092565b6000602082840312156200038057600080fd5b5051919050565b608051612a43620003b1600039600081816101e401528181610cfc01526115fa0152612a436000f3fe6080604052600436106101cd5760003560e01c80638ea98117116100f7578063bf17e55911610095578063f254bdc711610064578063f254bdc7146106c7578063f2fde38b14610704578063f3fef3a314610724578063fc2a88c31461074457600080fd5b8063bf17e559146105a6578063c3f909d4146105c6578063cdd8d88514610650578063da4f5e6d1461068a57600080fd5b8063a3907d71116100d1578063a3907d7114610532578063a4c0ed3614610547578063a608a1e114610567578063bed41a931461058657600080fd5b80638ea98117146104c55780639eccacf6146104e5578063a02e06161461051257600080fd5b806348baa1c51161016f578063650596541161013e578063650596541461042457806379ba5097146104445780637fb5d19d146104595780638da5cb5b1461047957600080fd5b806348baa1c5146102fc5780634b160935146103c757806357a8070a146103e757806362a504fc1461041157600080fd5b80631fe543e3116101ab5780631fe543e3146102875780632f2770db146102a75780633255c456146102bc5780634306d354146102dc57600080fd5b8063030932bb146101d257806307b18bde14610219578063181f5a771461023b575b600080fd5b3480156101de57600080fd5b506102067f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b34801561022557600080fd5b506102396102343660046123e5565b61075a565b005b34801561024757600080fd5b50604080518082018252601281527f56524656325772617070657220312e302e3000000000000000000000000000006020820152905161021091906127fb565b34801561029357600080fd5b506102396102a23660046124ea565b610836565b3480156102b357600080fd5b506102396108b7565b3480156102c857600080fd5b506102066102d736600461268a565b6108ed565b3480156102e857600080fd5b506102066102f7366004612623565b6109e5565b34801561030857600080fd5b506103866103173660046124b8565b60096020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000810463ffffffff16907801000000000000000000000000000000000000000000000000900467ffffffffffffffff1683565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff909216602084015267ffffffffffffffff1690820152606001610210565b3480156103d357600080fd5b506102066103e2366004612623565b610aec565b3480156103f357600080fd5b506008546104019060ff1681565b6040519015158152602001610210565b61020661041f36600461263e565b610be3565b34801561043057600080fd5b5061023961043f3660046123ca565b610f1a565b34801561045057600080fd5b50610239610f65565b34801561046557600080fd5b5061020661047436600461268a565b611062565b34801561048557600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610210565b3480156104d157600080fd5b506102396104e03660046123ca565b611168565b3480156104f157600080fd5b506002546104a09073ffffffffffffffffffffffffffffffffffffffff1681565b34801561051e57600080fd5b5061023961052d3660046123ca565b611273565b34801561053e57600080fd5b5061023961131e565b34801561055357600080fd5b5061023961056236600461240f565b611350565b34801561057357600080fd5b5060085461040190610100900460ff1681565b34801561059257600080fd5b506102396105a13660046126a6565b611836565b3480156105b257600080fd5b506102396105c1366004612623565b61198c565b3480156105d257600080fd5b506005546006546007546008546003546040805195865263ffffffff8086166020880152640100000000909504851690860152838316606086015268010000000000000000909204909216608084015260ff620100008304811660a085015260c084019190915263010000009091041660e082015261010001610210565b34801561065c57600080fd5b5060075461067590640100000000900463ffffffff1681565b60405163ffffffff9091168152602001610210565b34801561069657600080fd5b506006546104a0906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b3480156106d357600080fd5b506007546104a0906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561071057600080fd5b5061023961071f3660046123ca565b6119d3565b34801561073057600080fd5b5061023961073f3660046123e5565b6119e7565b34801561075057600080fd5b5061020660045481565b610762611ae2565b60008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d80600081146107bc576040519150601f19603f3d011682016040523d82523d6000602084013e6107c1565b606091505b5050905080610831576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f6661696c656420746f207769746864726177206e61746976650000000000000060448201526064015b60405180910390fd5b505050565b60025473ffffffffffffffffffffffffffffffffffffffff1633146108a9576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff9091166024820152604401610828565b6108b38282611b65565b5050565b6108bf611ae2565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b60085460009060ff1661095c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610828565b600854610100900460ff16156109ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610828565b6109de8363ffffffff1683611d4d565b9392505050565b60085460009060ff16610a54576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610828565b600854610100900460ff1615610ac6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610828565b6000610ad0611e23565b9050610ae38363ffffffff163a83611f83565b9150505b919050565b60085460009060ff16610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610828565b600854610100900460ff1615610bcd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610828565b610bdd8263ffffffff163a611d4d565b92915050565b600080610bef85612075565b90506000610c038663ffffffff163a611d4d565b905080341015610c6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610828565b6008546301000000900460ff1663ffffffff85161115610ceb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610828565b6040805160c08101825260035481527f0000000000000000000000000000000000000000000000000000000000000000602082015261ffff87169181019190915260075460009190606082019063ffffffff16610d48868b6128d1565b610d5291906128d1565b63ffffffff1681526020018663ffffffff168152602001610d8360405180602001604052806001151581525061208d565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690639b1c385e90610ddc90849060040161280e565b602060405180830381600087803b158015610df657600080fd5b505af1158015610e0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2e91906124d1565b6040805160608101825233815263ffffffff808b16602080840191825267ffffffffffffffff3a81168587019081526000888152600990935295909120935184549251955190911678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff9590931674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090921673ffffffffffffffffffffffffffffffffffffffff9190911617179290921691909117905593505050509392505050565b610f22611ae2565b6007805473ffffffffffffffffffffffffffffffffffffffff9092166c01000000000000000000000000026bffffffffffffffffffffffff909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314610fe6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610828565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60085460009060ff166110d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610828565b600854610100900460ff1615611143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610828565b600061114d611e23565b90506111608463ffffffff168483611f83565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906111a8575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561122c57336111cd60005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610828565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b61127b611ae2565b6006546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff16156112db576040517f2d118a6e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006805473ffffffffffffffffffffffffffffffffffffffff9092166c01000000000000000000000000026bffffffffffffffffffffffff909216919091179055565b611326611ae2565b600880547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055565b60085460ff166113bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f77726170706572206973206e6f7420636f6e66696775726564000000000000006044820152606401610828565b600854610100900460ff161561142e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f777261707065722069732064697361626c6564000000000000000000000000006044820152606401610828565b6006546c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1633146114bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f6f6e6c792063616c6c61626c652066726f6d204c494e4b0000000000000000006044820152606401610828565b600080806114cf8486018661263e565b92509250925060006114e084612075565b905060006114ec611e23565b905060006115018663ffffffff163a84611f83565b90508089101561156d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f66656520746f6f206c6f770000000000000000000000000000000000000000006044820152606401610828565b6008546301000000900460ff1663ffffffff851611156115e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f6e756d576f72647320746f6f20686967680000000000000000000000000000006044820152606401610828565b6040805160c08101825260035481527f0000000000000000000000000000000000000000000000000000000000000000602082015261ffff87169181019190915260075460009190606082019063ffffffff16611646878b6128d1565b61165091906128d1565b63ffffffff1681526020018663ffffffff1681526020016040518060200160405280600081525081525090506000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16639b1c385e836040518263ffffffff1660e01b81526004016116d9919061280e565b602060405180830381600087803b1580156116f357600080fd5b505af1158015611707573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172b91906124d1565b905060405180606001604052808d73ffffffffffffffffffffffffffffffffffffffff1681526020018963ffffffff1681526020013a67ffffffffffffffff168152506009600083815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548163ffffffff021916908363ffffffff16021790555060408201518160000160186101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555090505080600481905550505050505050505050505050565b61183e611ae2565b6007805463ffffffff9a8b167fffffffffffffffffffffffffffffffffffffffff00000000ffffffff000000009091161768010000000000000000998b168a02179055600880546003979097557fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000ffff9096166201000060ff988916027fffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffff161763010000009590971694909402959095177fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117909355600680546005949094557fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff9187167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009094169390931764010000000094871694909402939093179290921691909316909102179055565b611994611ae2565b6007805463ffffffff909216640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff909216919091179055565b6119db611ae2565b6119e481612149565b50565b6119ef611ae2565b6006546040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490526c010000000000000000000000009092049091169063a9059cbb90604401602060405180830381600087803b158015611a7457600080fd5b505af1158015611a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aac9190612496565b6108b3576040517f7c07fc4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005473ffffffffffffffffffffffffffffffffffffffff163314611b63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610828565b565b60008281526009602081815260408084208151606081018352815473ffffffffffffffffffffffffffffffffffffffff808216835274010000000000000000000000000000000000000000820463ffffffff1683870152780100000000000000000000000000000000000000000000000090910467ffffffffffffffff1693820193909352878652939092529290558051909116611c5f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610828565b600080631fe543e360e01b8585604051602401611c7d92919061286b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000611cf7846020015163ffffffff1685600001518461223f565b905080611d4557835160405173ffffffffffffffffffffffffffffffffffffffff9091169087907fc551b83c151f2d1c7eeb938ac59008e0409f1c1dc1e2f112449d4d79b458902290600090a35b505050505050565b6007546000908190611d6c90640100000000900463ffffffff1661228b565b60075463ffffffff680100000000000000008204811691611d8e9116876128b9565b611d9891906128b9565b611da29085612955565b611dac91906128b9565b6008549091508190600090606490611dcd9062010000900460ff16826128f9565b611dda9060ff1684612955565b611de4919061291e565b600654909150600090611e0e9068010000000000000000900463ffffffff1664e8d4a51000612955565b611e1890836128b9565b979650505050505050565b600654600754604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905160009363ffffffff16151592849283926c0100000000000000000000000090920473ffffffffffffffffffffffffffffffffffffffff169163feaf968c9160048082019260a092909190829003018186803b158015611eb057600080fd5b505afa158015611ec4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee89190612740565b509450909250849150508015611f0e5750611f038242612992565b60065463ffffffff16105b15611f1857506005545b60008112156109de576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e76616c6964204c494e4b20776569207072696365000000000000000000006044820152606401610828565b6007546000908190611fa290640100000000900463ffffffff1661228b565b60075463ffffffff680100000000000000008204811691611fc49116886128b9565b611fce91906128b9565b611fd89086612955565b611fe291906128b9565b9050600083611ff983670de0b6b3a7640000612955565b612003919061291e565b6008549091506000906064906120229062010000900460ff16826128f9565b61202f9060ff1684612955565b612039919061291e565b60065490915060009061205f90640100000000900463ffffffff1664e8d4a51000612955565b61206990836128b9565b98975050505050505050565b6000612082603f83612932565b610bdd9060016128d1565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa826040516024016120c691511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b73ffffffffffffffffffffffffffffffffffffffff81163314156121c9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610828565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b60005a61138881101561225157600080fd5b61138881039050846040820482031161226957600080fd5b50823b61227557600080fd5b60008083516020850160008789f1949350505050565b60004661229781612344565b1561233b576000606c73ffffffffffffffffffffffffffffffffffffffff166341b247a86040518163ffffffff1660e01b815260040160c06040518083038186803b1580156122e557600080fd5b505afa1580156122f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061231d91906125d9565b5050505091505083608c61233191906128b9565b6111609082612955565b50600092915050565b600061a4b1821480612358575062066eed82145b80610bdd57505062066eee1490565b803573ffffffffffffffffffffffffffffffffffffffff81168114610ae757600080fd5b803563ffffffff81168114610ae757600080fd5b803560ff81168114610ae757600080fd5b805169ffffffffffffffffffff81168114610ae757600080fd5b6000602082840312156123dc57600080fd5b6109de82612367565b600080604083850312156123f857600080fd5b61240183612367565b946020939093013593505050565b6000806000806060858703121561242557600080fd5b61242e85612367565b935060208501359250604085013567ffffffffffffffff8082111561245257600080fd5b818701915087601f83011261246657600080fd5b81358181111561247557600080fd5b88602082850101111561248757600080fd5b95989497505060200194505050565b6000602082840312156124a857600080fd5b815180151581146109de57600080fd5b6000602082840312156124ca57600080fd5b5035919050565b6000602082840312156124e357600080fd5b5051919050565b600080604083850312156124fd57600080fd5b8235915060208084013567ffffffffffffffff8082111561251d57600080fd5b818601915086601f83011261253157600080fd5b81358181111561254357612543612a07565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561258657612586612a07565b604052828152858101935084860182860187018b10156125a557600080fd5b600095505b838610156125c85780358552600195909501949386019386016125aa565b508096505050505050509250929050565b60008060008060008060c087890312156125f257600080fd5b865195506020870151945060408701519350606087015192506080870151915060a087015190509295509295509295565b60006020828403121561263557600080fd5b6109de8261238b565b60008060006060848603121561265357600080fd5b61265c8461238b565b9250602084013561ffff8116811461267357600080fd5b91506126816040850161238b565b90509250925092565b6000806040838503121561269d57600080fd5b6124018361238b565b60008060008060008060008060006101208a8c0312156126c557600080fd5b6126ce8a61238b565b98506126dc60208b0161238b565b97506126ea60408b0161239f565b965060608a013595506126ff60808b0161239f565b945061270d60a08b0161238b565b935060c08a0135925061272260e08b0161238b565b91506127316101008b0161238b565b90509295985092959850929598565b600080600080600060a0868803121561275857600080fd5b612761866123b0565b9450602086015193506040860151925060608601519150612784608087016123b0565b90509295509295909350565b6000815180845260005b818110156127b65760208185018101518683018201520161279a565b818111156127c8576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006109de6020830184612790565b60208152815160208201526020820151604082015261ffff60408301511660608201526000606083015163ffffffff80821660808501528060808601511660a0850152505060a083015160c08084015261116060e0840182612790565b6000604082018483526020604081850152818551808452606086019150828701935060005b818110156128ac57845183529383019391830191600101612890565b5090979650505050505050565b600082198211156128cc576128cc6129a9565b500190565b600063ffffffff8083168185168083038211156128f0576128f06129a9565b01949350505050565b600060ff821660ff84168060ff03821115612916576129166129a9565b019392505050565b60008261292d5761292d6129d8565b500490565b600063ffffffff80841680612949576129496129d8565b92169190910492915050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561298d5761298d6129a9565b500290565b6000828210156129a4576129a46129a9565b500390565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var VRFV2PlusWrapperABI = VRFV2PlusWrapperMetaData.ABI var VRFV2PlusWrapperBin = VRFV2PlusWrapperMetaData.Bin -func DeployVRFV2PlusWrapper(auth *bind.TransactOpts, backend bind.ContractBackend, _link common.Address, _linkEthFeed common.Address, _coordinator common.Address) (common.Address, *types.Transaction, *VRFV2PlusWrapper, error) { +func DeployVRFV2PlusWrapper(auth *bind.TransactOpts, backend bind.ContractBackend, _link common.Address, _linkNativeFeed common.Address, _coordinator common.Address) (common.Address, *types.Transaction, *VRFV2PlusWrapper, error) { parsed, err := VRFV2PlusWrapperMetaData.GetAbi() if err != nil { return common.Address{}, nil, nil, err @@ -48,7 +48,7 @@ func DeployVRFV2PlusWrapper(auth *bind.TransactOpts, backend bind.ContractBacken return common.Address{}, nil, nil, errors.New("GetABI returned nil") } - address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VRFV2PlusWrapperBin), backend, _link, _linkEthFeed, _coordinator) + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(VRFV2PlusWrapperBin), backend, _link, _linkNativeFeed, _coordinator) if err != nil { return common.Address{}, nil, nil, err } @@ -171,28 +171,6 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorRaw) Transact(opts *bind.Tran return _VRFV2PlusWrapper.Contract.contract.Transact(opts, method, params...) } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) COORDINATOR(opts *bind.CallOpts) (common.Address, error) { - var out []interface{} - err := _VRFV2PlusWrapper.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 (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) COORDINATOR() (common.Address, error) { - return _VRFV2PlusWrapper.Contract.COORDINATOR(&_VRFV2PlusWrapper.CallOpts) -} - -func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) COORDINATOR() (common.Address, error) { - return _VRFV2PlusWrapper.Contract.COORDINATOR(&_VRFV2PlusWrapper.CallOpts) -} - func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) SUBSCRIPTIONID(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} err := _VRFV2PlusWrapper.contract.Call(opts, &out, "SUBSCRIPTION_ID") @@ -396,7 +374,7 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) SCallbacks(opts *bind.CallOpts, outstruct.CallbackAddress = *abi.ConvertType(out[0], new(common.Address)).(*common.Address) outstruct.CallbackGasLimit = *abi.ConvertType(out[1], new(uint32)).(*uint32) - outstruct.RequestGasPrice = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.RequestGasPrice = *abi.ConvertType(out[2], new(uint64)).(*uint64) return *outstruct, err @@ -502,9 +480,9 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) SLink() (common.Address, return _VRFV2PlusWrapper.Contract.SLink(&_VRFV2PlusWrapper.CallOpts) } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) SLinkEthFeed(opts *bind.CallOpts) (common.Address, error) { +func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) SLinkNativeFeed(opts *bind.CallOpts) (common.Address, error) { var out []interface{} - err := _VRFV2PlusWrapper.contract.Call(opts, &out, "s_linkEthFeed") + err := _VRFV2PlusWrapper.contract.Call(opts, &out, "s_linkNativeFeed") if err != nil { return *new(common.Address), err @@ -516,12 +494,12 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) SLinkEthFeed(opts *bind.CallOpt } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) SLinkEthFeed() (common.Address, error) { - return _VRFV2PlusWrapper.Contract.SLinkEthFeed(&_VRFV2PlusWrapper.CallOpts) +func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) SLinkNativeFeed() (common.Address, error) { + return _VRFV2PlusWrapper.Contract.SLinkNativeFeed(&_VRFV2PlusWrapper.CallOpts) } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) SLinkEthFeed() (common.Address, error) { - return _VRFV2PlusWrapper.Contract.SLinkEthFeed(&_VRFV2PlusWrapper.CallOpts) +func (_VRFV2PlusWrapper *VRFV2PlusWrapperCallerSession) SLinkNativeFeed() (common.Address, error) { + return _VRFV2PlusWrapper.Contract.SLinkNativeFeed(&_VRFV2PlusWrapper.CallOpts) } func (_VRFV2PlusWrapper *VRFV2PlusWrapperCaller) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) { @@ -640,16 +618,16 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) RequestRandomWordsIn return _VRFV2PlusWrapper.Contract.RequestRandomWordsInNative(&_VRFV2PlusWrapper.TransactOpts, _callbackGasLimit, _requestConfirmations, _numWords) } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) SetConfig(opts *bind.TransactOpts, _wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _wrapperPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8) (*types.Transaction, error) { - return _VRFV2PlusWrapper.contract.Transact(opts, "setConfig", _wrapperGasOverhead, _coordinatorGasOverhead, _wrapperPremiumPercentage, _keyHash, _maxNumWords) +func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) SetConfig(opts *bind.TransactOpts, _wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _wrapperPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, stalenessSeconds uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeLinkPPM uint32, fulfillmentFlatFeeNativePPM uint32) (*types.Transaction, error) { + return _VRFV2PlusWrapper.contract.Transact(opts, "setConfig", _wrapperGasOverhead, _coordinatorGasOverhead, _wrapperPremiumPercentage, _keyHash, _maxNumWords, stalenessSeconds, fallbackWeiPerUnitLink, fulfillmentFlatFeeLinkPPM, fulfillmentFlatFeeNativePPM) } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) SetConfig(_wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _wrapperPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8) (*types.Transaction, error) { - return _VRFV2PlusWrapper.Contract.SetConfig(&_VRFV2PlusWrapper.TransactOpts, _wrapperGasOverhead, _coordinatorGasOverhead, _wrapperPremiumPercentage, _keyHash, _maxNumWords) +func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) SetConfig(_wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _wrapperPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, stalenessSeconds uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeLinkPPM uint32, fulfillmentFlatFeeNativePPM uint32) (*types.Transaction, error) { + return _VRFV2PlusWrapper.Contract.SetConfig(&_VRFV2PlusWrapper.TransactOpts, _wrapperGasOverhead, _coordinatorGasOverhead, _wrapperPremiumPercentage, _keyHash, _maxNumWords, stalenessSeconds, fallbackWeiPerUnitLink, fulfillmentFlatFeeLinkPPM, fulfillmentFlatFeeNativePPM) } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) SetConfig(_wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _wrapperPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8) (*types.Transaction, error) { - return _VRFV2PlusWrapper.Contract.SetConfig(&_VRFV2PlusWrapper.TransactOpts, _wrapperGasOverhead, _coordinatorGasOverhead, _wrapperPremiumPercentage, _keyHash, _maxNumWords) +func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) SetConfig(_wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _wrapperPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, stalenessSeconds uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeLinkPPM uint32, fulfillmentFlatFeeNativePPM uint32) (*types.Transaction, error) { + return _VRFV2PlusWrapper.Contract.SetConfig(&_VRFV2PlusWrapper.TransactOpts, _wrapperGasOverhead, _coordinatorGasOverhead, _wrapperPremiumPercentage, _keyHash, _maxNumWords, stalenessSeconds, fallbackWeiPerUnitLink, fulfillmentFlatFeeLinkPPM, fulfillmentFlatFeeNativePPM) } func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error) { @@ -688,16 +666,16 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) SetLINK(link common. return _VRFV2PlusWrapper.Contract.SetLINK(&_VRFV2PlusWrapper.TransactOpts, link) } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) SetLinkEthFeed(opts *bind.TransactOpts, linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFV2PlusWrapper.contract.Transact(opts, "setLinkEthFeed", linkEthFeed) +func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) SetLinkNativeFeed(opts *bind.TransactOpts, linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapper.contract.Transact(opts, "setLinkNativeFeed", linkNativeFeed) } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) SetLinkEthFeed(linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFV2PlusWrapper.Contract.SetLinkEthFeed(&_VRFV2PlusWrapper.TransactOpts, linkEthFeed) +func (_VRFV2PlusWrapper *VRFV2PlusWrapperSession) SetLinkNativeFeed(linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapper.Contract.SetLinkNativeFeed(&_VRFV2PlusWrapper.TransactOpts, linkNativeFeed) } -func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) SetLinkEthFeed(linkEthFeed common.Address) (*types.Transaction, error) { - return _VRFV2PlusWrapper.Contract.SetLinkEthFeed(&_VRFV2PlusWrapper.TransactOpts, linkEthFeed) +func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactorSession) SetLinkNativeFeed(linkNativeFeed common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapper.Contract.SetLinkNativeFeed(&_VRFV2PlusWrapper.TransactOpts, linkNativeFeed) } func (_VRFV2PlusWrapper *VRFV2PlusWrapperTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { @@ -1157,7 +1135,7 @@ type GetConfig struct { type SCallbacks struct { CallbackAddress common.Address CallbackGasLimit uint32 - RequestGasPrice *big.Int + RequestGasPrice uint64 } func (_VRFV2PlusWrapper *VRFV2PlusWrapper) ParseLog(log types.Log) (generated.AbigenLog, error) { @@ -1191,8 +1169,6 @@ func (_VRFV2PlusWrapper *VRFV2PlusWrapper) Address() common.Address { } type VRFV2PlusWrapperInterface interface { - COORDINATOR(opts *bind.CallOpts) (common.Address, error) - SUBSCRIPTIONID(opts *bind.CallOpts) (*big.Int, error) CalculateRequestPrice(opts *bind.CallOpts, _callbackGasLimit uint32) (*big.Int, error) @@ -1223,7 +1199,7 @@ type VRFV2PlusWrapperInterface interface { SLink(opts *bind.CallOpts) (common.Address, error) - SLinkEthFeed(opts *bind.CallOpts) (common.Address, error) + SLinkNativeFeed(opts *bind.CallOpts) (common.Address, error) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) @@ -1241,7 +1217,7 @@ type VRFV2PlusWrapperInterface interface { RequestRandomWordsInNative(opts *bind.TransactOpts, _callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32) (*types.Transaction, error) - SetConfig(opts *bind.TransactOpts, _wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _wrapperPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8) (*types.Transaction, error) + SetConfig(opts *bind.TransactOpts, _wrapperGasOverhead uint32, _coordinatorGasOverhead uint32, _wrapperPremiumPercentage uint8, _keyHash [32]byte, _maxNumWords uint8, stalenessSeconds uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeLinkPPM uint32, fulfillmentFlatFeeNativePPM uint32) (*types.Transaction, error) SetCoordinator(opts *bind.TransactOpts, _vrfCoordinator common.Address) (*types.Transaction, error) @@ -1249,7 +1225,7 @@ type VRFV2PlusWrapperInterface interface { SetLINK(opts *bind.TransactOpts, link common.Address) (*types.Transaction, error) - SetLinkEthFeed(opts *bind.TransactOpts, linkEthFeed common.Address) (*types.Transaction, error) + SetLinkNativeFeed(opts *bind.TransactOpts, linkNativeFeed common.Address) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) diff --git a/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer/vrfv2plus_wrapper_load_test_consumer.go b/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer/vrfv2plus_wrapper_load_test_consumer.go new file mode 100644 index 0000000000..4318b4bdea --- /dev/null +++ b/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer/vrfv2plus_wrapper_load_test_consumer.go @@ -0,0 +1,1210 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package vrfv2plus_wrapper_load_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 VRFV2PlusWrapperLoadTestConsumerMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_vrfV2PlusWrapper\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"LINKAlreadySet\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"payment\",\"type\":\"uint256\"}],\"name\":\"WrappedRequestFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"}],\"name\":\"WrapperRequestMade\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getBalance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getWrapper\",\"outputs\":[{\"internalType\":\"contractVRFV2PlusWrapperInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestCount\",\"type\":\"uint16\"}],\"name\":\"makeRequests\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestCount\",\"type\":\"uint16\"}],\"name\":\"makeRequestsNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"_randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_averageFulfillmentInMillions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fastestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"paid\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"native\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_responseCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_link\",\"type\":\"address\"}],\"name\":\"setLinkToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawLink\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x6080604052600060065560006007556103e76008553480156200002157600080fd5b5060405162001def38038062001def8339810160408190526200004491620001f2565b3380600084846001600160a01b038216156200007657600080546001600160a01b0319166001600160a01b0384161790555b600180546001600160a01b0319166001600160a01b03928316179055831615159050620000ea5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600280546001600160a01b0319166001600160a01b03848116919091179091558116156200011d576200011d8162000128565b50505050506200022a565b6001600160a01b038116331415620001835760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401620000e1565b600380546001600160a01b0319166001600160a01b03838116918217909255600254604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b80516001600160a01b0381168114620001ed57600080fd5b919050565b600080604083850312156200020657600080fd5b6200021183620001d5565b91506200022160208401620001d5565b90509250929050565b611bb5806200023a6000396000f3fe6080604052600436106101635760003560e01c80638f6b7070116100c0578063d826f88f11610074578063dc1670db11610059578063dc1670db14610421578063f176596214610437578063f2fde38b1461045757600080fd5b8063d826f88f146103c2578063d8a4676f146103ee57600080fd5b8063a168fa89116100a5578063a168fa89146102f7578063afacbf9c1461038c578063b1e21749146103ac57600080fd5b80638f6b7070146102ac5780639c24ea40146102d757600080fd5b806374dba124116101175780637a8042bd116100fc5780637a8042bd1461022057806384276d81146102405780638da5cb5b1461026057600080fd5b806374dba124146101f557806379ba50971461020b57600080fd5b80631fe543e3116101485780631fe543e3146101a7578063557d2e92146101c9578063737144bc146101df57600080fd5b806312065fe01461016f5780631757f11c1461019157600080fd5b3661016a57005b600080fd5b34801561017b57600080fd5b50475b6040519081526020015b60405180910390f35b34801561019d57600080fd5b5061017e60075481565b3480156101b357600080fd5b506101c76101c23660046117c2565b610477565b005b3480156101d557600080fd5b5061017e60055481565b3480156101eb57600080fd5b5061017e60065481565b34801561020157600080fd5b5061017e60085481565b34801561021757600080fd5b506101c7610530565b34801561022c57600080fd5b506101c761023b366004611790565b610631565b34801561024c57600080fd5b506101c761025b366004611790565b61071b565b34801561026c57600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610188565b3480156102b857600080fd5b5060015473ffffffffffffffffffffffffffffffffffffffff16610287565b3480156102e357600080fd5b506101c76102f2366004611731565b61080b565b34801561030357600080fd5b50610355610312366004611790565b600b602052600090815260409020805460018201546003830154600484015460058501546006860154600790960154949560ff9485169593949293919290911687565b604080519788529515156020880152948601939093526060850191909152608084015260a0830152151560c082015260e001610188565b34801561039857600080fd5b506101c76103a73660046118b1565b6108a2565b3480156103b857600080fd5b5061017e60095481565b3480156103ce57600080fd5b506101c76000600681905560078190556103e76008556005819055600455565b3480156103fa57600080fd5b5061040e610409366004611790565b610b12565b6040516101889796959493929190611a01565b34801561042d57600080fd5b5061017e60045481565b34801561044357600080fd5b506101c76104523660046118b1565b610c95565b34801561046357600080fd5b506101c7610472366004611731565b610efd565b60015473ffffffffffffffffffffffffffffffffffffffff163314610522576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f6f6e6c792056524620563220506c757320777261707065722063616e2066756c60448201527f66696c6c0000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61052c8282610f11565b5050565b60035473ffffffffffffffffffffffffffffffffffffffff1633146105b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610519565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000008082163390811790935560038054909116905560405173ffffffffffffffffffffffffffffffffffffffff909116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6106396110f0565b60005473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb61067660025473ffffffffffffffffffffffffffffffffffffffff1690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff909116600482015260248101849052604401602060405180830381600087803b1580156106e357600080fd5b505af11580156106f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052c919061176e565b6107236110f0565b600061074460025473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d806000811461079b576040519150601f19603f3d011682016040523d82523d6000602084013e6107a0565b606091505b505090508061052c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f77697468647261774e6174697665206661696c656400000000000000000000006044820152606401610519565b60005473ffffffffffffffffffffffffffffffffffffffff161561085b576040517f64f778ae00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6108aa6110f0565b60005b8161ffff168161ffff161015610b0b5760006108ca868686611173565b6009819055905060006108db611378565b6001546040517f4306d35400000000000000000000000000000000000000000000000000000000815263ffffffff8a16600482015291925060009173ffffffffffffffffffffffffffffffffffffffff90911690634306d3549060240160206040518083038186803b15801561095057600080fd5b505afa158015610964573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098891906117a9565b604080516101008101825282815260006020808301828152845183815280830186528486019081524260608601526080850184905260a0850189905260c0850184905260e08501849052898452600b8352949092208351815591516001830180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790559251805194955091939092610a309260028501929101906116a6565b50606082015160038201556080820151600482015560a082015160058083019190915560c0830151600683015560e090920151600790910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558054906000610aa383611b11565b90915550506000838152600a6020526040908190208390555183907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec490610aed9084815260200190565b60405180910390a25050508080610b0390611aef565b9150506108ad565b5050505050565b6000818152600b602052604081205481906060908290819081908190610b94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610519565b6000888152600b6020908152604080832081516101008101835281548152600182015460ff16151581850152600282018054845181870281018701865281815292959394860193830182828015610c0a57602002820191906000526020600020905b815481526020019060010190808311610bf6575b50505050508152602001600382015481526020016004820154815260200160058201548152602001600682015481526020016007820160009054906101000a900460ff1615151515815250509050806000015181602001518260400151836060015184608001518560a001518660c00151975097509750975097509750975050919395979092949650565b610c9d6110f0565b60005b8161ffff168161ffff161015610b0b576000610cbd868686611415565b600981905590506000610cce611378565b6001546040517f4b16093500000000000000000000000000000000000000000000000000000000815263ffffffff8a16600482015291925060009173ffffffffffffffffffffffffffffffffffffffff90911690634b1609359060240160206040518083038186803b158015610d4357600080fd5b505afa158015610d57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7b91906117a9565b604080516101008101825282815260006020808301828152845183815280830186528486019081524260608601526080850184905260a0850189905260c08501849052600160e086018190528a8552600b84529590932084518155905194810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001695151595909517909455905180519495509193610e2292600285019201906116a6565b50606082015160038201556080820151600482015560a082015160058083019190915560c0830151600683015560e090920151600790910180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790558054906000610e9583611b11565b90915550506000838152600a6020526040908190208390555183907f5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec490610edf9084815260200190565b60405180910390a25050508080610ef590611aef565b915050610ca0565b610f056110f0565b610f0e81611588565b50565b6000828152600b6020526040902054610f86576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f72657175657374206e6f7420666f756e640000000000000000000000000000006044820152606401610519565b6000610f90611378565b6000848152600a602052604081205491925090610fad9083611ad8565b90506000610fbe82620f4240611a9b565b9050600754821115610fd05760078290555b6008548210610fe157600854610fe3565b815b600855600454610ff35780611026565b600454611001906001611a48565b816004546006546110129190611a9b565b61101c9190611a48565b6110269190611a60565b6006556004805490600061103983611b11565b90915550506000858152600b60209081526040909120600181810180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790558551611091926002909201918701906116a6565b506000858152600b602052604090819020426004820155600681018590555490517f6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b916110e191889188916119d8565b60405180910390a15050505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314611171576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610519565b565b600080546001546040517f4306d35400000000000000000000000000000000000000000000000000000000815263ffffffff8716600482015273ffffffffffffffffffffffffffffffffffffffff92831692634000aea09216908190634306d3549060240160206040518083038186803b1580156111f057600080fd5b505afa158015611204573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122891906117a9565b6040805163ffffffff808b16602083015261ffff8a169282019290925290871660608201526080016040516020818303038152906040526040518463ffffffff1660e01b815260040161127d93929190611940565b602060405180830381600087803b15801561129757600080fd5b505af11580156112ab573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cf919061176e565b50600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fc2a88c36040518163ffffffff1660e01b815260040160206040518083038186803b15801561133857600080fd5b505afa15801561134c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137091906117a9565b949350505050565b6000466113848161167f565b1561140e57606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b1580156113d057600080fd5b505afa1580156113e4573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061140891906117a9565b91505090565b4391505090565b6001546040517f4b16093500000000000000000000000000000000000000000000000000000000815263ffffffff85166004820152600091829173ffffffffffffffffffffffffffffffffffffffff90911690634b1609359060240160206040518083038186803b15801561148957600080fd5b505afa15801561149d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114c191906117a9565b6001546040517f62a504fc00000000000000000000000000000000000000000000000000000000815263ffffffff808916600483015261ffff881660248301528616604482015291925073ffffffffffffffffffffffffffffffffffffffff16906362a504fc9083906064016020604051808303818588803b15801561154657600080fd5b505af115801561155a573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061157f91906117a9565b95945050505050565b73ffffffffffffffffffffffffffffffffffffffff8116331415611608576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610519565b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600254604051919216907fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae127890600090a350565b600061a4b1821480611693575062066eed82145b806116a0575062066eee82145b92915050565b8280548282559060005260206000209081019282156116e1579160200282015b828111156116e15782518255916020019190600101906116c6565b506116ed9291506116f1565b5090565b5b808211156116ed57600081556001016116f2565b803561ffff8116811461171857600080fd5b919050565b803563ffffffff8116811461171857600080fd5b60006020828403121561174357600080fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461176757600080fd5b9392505050565b60006020828403121561178057600080fd5b8151801515811461176757600080fd5b6000602082840312156117a257600080fd5b5035919050565b6000602082840312156117bb57600080fd5b5051919050565b600080604083850312156117d557600080fd5b8235915060208084013567ffffffffffffffff808211156117f557600080fd5b818601915086601f83011261180957600080fd5b81358181111561181b5761181b611b79565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110858211171561185e5761185e611b79565b604052828152858101935084860182860187018b101561187d57600080fd5b600095505b838610156118a0578035855260019590950194938601938601611882565b508096505050505050509250929050565b600080600080608085870312156118c757600080fd5b6118d08561171d565b93506118de60208601611706565b92506118ec6040860161171d565b91506118fa60608601611706565b905092959194509250565b600081518084526020808501945080840160005b8381101561193557815187529582019590820190600101611919565b509495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8416815260006020848184015260606040840152835180606085015260005b8181101561199057858101830151858201608001528201611974565b818111156119a2576000608083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160800195945050505050565b8381526060602082015260006119f16060830185611905565b9050826040830152949350505050565b878152861515602082015260e060408201526000611a2260e0830188611905565b90508560608301528460808301528360a08301528260c083015298975050505050505050565b60008219821115611a5b57611a5b611b4a565b500190565b600082611a96577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611ad357611ad3611b4a565b500290565b600082821015611aea57611aea611b4a565b500390565b600061ffff80831681811415611b0757611b07611b4a565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415611b4357611b43611b4a565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", +} + +var VRFV2PlusWrapperLoadTestConsumerABI = VRFV2PlusWrapperLoadTestConsumerMetaData.ABI + +var VRFV2PlusWrapperLoadTestConsumerBin = VRFV2PlusWrapperLoadTestConsumerMetaData.Bin + +func DeployVRFV2PlusWrapperLoadTestConsumer(auth *bind.TransactOpts, backend bind.ContractBackend, _link common.Address, _vrfV2PlusWrapper common.Address) (common.Address, *types.Transaction, *VRFV2PlusWrapperLoadTestConsumer, error) { + parsed, err := VRFV2PlusWrapperLoadTestConsumerMetaData.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(VRFV2PlusWrapperLoadTestConsumerBin), backend, _link, _vrfV2PlusWrapper) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &VRFV2PlusWrapperLoadTestConsumer{VRFV2PlusWrapperLoadTestConsumerCaller: VRFV2PlusWrapperLoadTestConsumerCaller{contract: contract}, VRFV2PlusWrapperLoadTestConsumerTransactor: VRFV2PlusWrapperLoadTestConsumerTransactor{contract: contract}, VRFV2PlusWrapperLoadTestConsumerFilterer: VRFV2PlusWrapperLoadTestConsumerFilterer{contract: contract}}, nil +} + +type VRFV2PlusWrapperLoadTestConsumer struct { + address common.Address + abi abi.ABI + VRFV2PlusWrapperLoadTestConsumerCaller + VRFV2PlusWrapperLoadTestConsumerTransactor + VRFV2PlusWrapperLoadTestConsumerFilterer +} + +type VRFV2PlusWrapperLoadTestConsumerCaller struct { + contract *bind.BoundContract +} + +type VRFV2PlusWrapperLoadTestConsumerTransactor struct { + contract *bind.BoundContract +} + +type VRFV2PlusWrapperLoadTestConsumerFilterer struct { + contract *bind.BoundContract +} + +type VRFV2PlusWrapperLoadTestConsumerSession struct { + Contract *VRFV2PlusWrapperLoadTestConsumer + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type VRFV2PlusWrapperLoadTestConsumerCallerSession struct { + Contract *VRFV2PlusWrapperLoadTestConsumerCaller + CallOpts bind.CallOpts +} + +type VRFV2PlusWrapperLoadTestConsumerTransactorSession struct { + Contract *VRFV2PlusWrapperLoadTestConsumerTransactor + TransactOpts bind.TransactOpts +} + +type VRFV2PlusWrapperLoadTestConsumerRaw struct { + Contract *VRFV2PlusWrapperLoadTestConsumer +} + +type VRFV2PlusWrapperLoadTestConsumerCallerRaw struct { + Contract *VRFV2PlusWrapperLoadTestConsumerCaller +} + +type VRFV2PlusWrapperLoadTestConsumerTransactorRaw struct { + Contract *VRFV2PlusWrapperLoadTestConsumerTransactor +} + +func NewVRFV2PlusWrapperLoadTestConsumer(address common.Address, backend bind.ContractBackend) (*VRFV2PlusWrapperLoadTestConsumer, error) { + abi, err := abi.JSON(strings.NewReader(VRFV2PlusWrapperLoadTestConsumerABI)) + if err != nil { + return nil, err + } + contract, err := bindVRFV2PlusWrapperLoadTestConsumer(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &VRFV2PlusWrapperLoadTestConsumer{address: address, abi: abi, VRFV2PlusWrapperLoadTestConsumerCaller: VRFV2PlusWrapperLoadTestConsumerCaller{contract: contract}, VRFV2PlusWrapperLoadTestConsumerTransactor: VRFV2PlusWrapperLoadTestConsumerTransactor{contract: contract}, VRFV2PlusWrapperLoadTestConsumerFilterer: VRFV2PlusWrapperLoadTestConsumerFilterer{contract: contract}}, nil +} + +func NewVRFV2PlusWrapperLoadTestConsumerCaller(address common.Address, caller bind.ContractCaller) (*VRFV2PlusWrapperLoadTestConsumerCaller, error) { + contract, err := bindVRFV2PlusWrapperLoadTestConsumer(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &VRFV2PlusWrapperLoadTestConsumerCaller{contract: contract}, nil +} + +func NewVRFV2PlusWrapperLoadTestConsumerTransactor(address common.Address, transactor bind.ContractTransactor) (*VRFV2PlusWrapperLoadTestConsumerTransactor, error) { + contract, err := bindVRFV2PlusWrapperLoadTestConsumer(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &VRFV2PlusWrapperLoadTestConsumerTransactor{contract: contract}, nil +} + +func NewVRFV2PlusWrapperLoadTestConsumerFilterer(address common.Address, filterer bind.ContractFilterer) (*VRFV2PlusWrapperLoadTestConsumerFilterer, error) { + contract, err := bindVRFV2PlusWrapperLoadTestConsumer(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &VRFV2PlusWrapperLoadTestConsumerFilterer{contract: contract}, nil +} + +func bindVRFV2PlusWrapperLoadTestConsumer(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := VRFV2PlusWrapperLoadTestConsumerMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.VRFV2PlusWrapperLoadTestConsumerCaller.contract.Call(opts, result, method, params...) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.VRFV2PlusWrapperLoadTestConsumerTransactor.contract.Transfer(opts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.VRFV2PlusWrapperLoadTestConsumerTransactor.contract.Transact(opts, method, params...) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.contract.Call(opts, result, method, params...) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.contract.Transfer(opts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.contract.Transact(opts, method, params...) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) GetBalance(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.contract.Call(opts, &out, "getBalance") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) GetBalance() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.GetBalance(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) GetBalance() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.GetBalance(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) GetRequestStatus(opts *bind.CallOpts, _requestId *big.Int) (GetRequestStatus, + + error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.contract.Call(opts, &out, "getRequestStatus", _requestId) + + outstruct := new(GetRequestStatus) + if err != nil { + return *outstruct, err + } + + outstruct.Paid = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Fulfilled = *abi.ConvertType(out[1], new(bool)).(*bool) + outstruct.RandomWords = *abi.ConvertType(out[2], new([]*big.Int)).(*[]*big.Int) + outstruct.RequestTimestamp = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.FulfilmentTimestamp = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + outstruct.RequestBlockNumber = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) + outstruct.FulfilmentBlockNumber = *abi.ConvertType(out[6], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) GetRequestStatus(_requestId *big.Int) (GetRequestStatus, + + error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.GetRequestStatus(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts, _requestId) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) GetRequestStatus(_requestId *big.Int) (GetRequestStatus, + + error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.GetRequestStatus(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts, _requestId) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) GetWrapper(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.contract.Call(opts, &out, "getWrapper") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) GetWrapper() (common.Address, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.GetWrapper(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) GetWrapper() (common.Address, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.GetWrapper(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) Owner(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.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 (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) Owner() (common.Address, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.Owner(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) Owner() (common.Address, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.Owner(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.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 (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) SAverageFulfillmentInMillions() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SAverageFulfillmentInMillions(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) SAverageFulfillmentInMillions() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SAverageFulfillmentInMillions(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.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 (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) SFastestFulfillment() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SFastestFulfillment(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) SFastestFulfillment() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SFastestFulfillment(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) SLastRequestId(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.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 (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) SLastRequestId() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SLastRequestId(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) SLastRequestId() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SLastRequestId(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) SRequestCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.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 (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) SRequestCount() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SRequestCount(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) SRequestCount() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SRequestCount(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) SRequests(opts *bind.CallOpts, arg0 *big.Int) (SRequests, + + error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.contract.Call(opts, &out, "s_requests", arg0) + + outstruct := new(SRequests) + if err != nil { + return *outstruct, err + } + + outstruct.Paid = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Fulfilled = *abi.ConvertType(out[1], new(bool)).(*bool) + 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) + outstruct.Native = *abi.ConvertType(out[6], new(bool)).(*bool) + + return *outstruct, err + +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) SRequests(arg0 *big.Int) (SRequests, + + error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SRequests(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts, arg0) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) SRequests(arg0 *big.Int) (SRequests, + + error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SRequests(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts, arg0) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) SResponseCount(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.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 (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) SResponseCount() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SResponseCount(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) SResponseCount() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SResponseCount(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCaller) SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusWrapperLoadTestConsumer.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 (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) SSlowestFulfillment() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SSlowestFulfillment(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerCallerSession) SSlowestFulfillment() (*big.Int, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SSlowestFulfillment(&_VRFV2PlusWrapperLoadTestConsumer.CallOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.Transact(opts, "acceptOwnership") +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.AcceptOwnership(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) AcceptOwnership() (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.AcceptOwnership(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) MakeRequests(opts *bind.TransactOpts, _callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32, _requestCount uint16) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.Transact(opts, "makeRequests", _callbackGasLimit, _requestConfirmations, _numWords, _requestCount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) MakeRequests(_callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32, _requestCount uint16) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.MakeRequests(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, _callbackGasLimit, _requestConfirmations, _numWords, _requestCount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) MakeRequests(_callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32, _requestCount uint16) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.MakeRequests(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, _callbackGasLimit, _requestConfirmations, _numWords, _requestCount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) MakeRequestsNative(opts *bind.TransactOpts, _callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32, _requestCount uint16) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.Transact(opts, "makeRequestsNative", _callbackGasLimit, _requestConfirmations, _numWords, _requestCount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) MakeRequestsNative(_callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32, _requestCount uint16) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.MakeRequestsNative(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, _callbackGasLimit, _requestConfirmations, _numWords, _requestCount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) MakeRequestsNative(_callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32, _requestCount uint16) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.MakeRequestsNative(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, _callbackGasLimit, _requestConfirmations, _numWords, _requestCount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) RawFulfillRandomWords(opts *bind.TransactOpts, _requestId *big.Int, _randomWords []*big.Int) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.Transact(opts, "rawFulfillRandomWords", _requestId, _randomWords) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) RawFulfillRandomWords(_requestId *big.Int, _randomWords []*big.Int) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.RawFulfillRandomWords(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, _requestId, _randomWords) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) RawFulfillRandomWords(_requestId *big.Int, _randomWords []*big.Int) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.RawFulfillRandomWords(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, _requestId, _randomWords) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) Reset(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.Transact(opts, "reset") +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) Reset() (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.Reset(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) Reset() (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.Reset(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) SetLinkToken(opts *bind.TransactOpts, _link common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.Transact(opts, "setLinkToken", _link) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) SetLinkToken(_link common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SetLinkToken(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, _link) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) SetLinkToken(_link common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.SetLinkToken(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, _link) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.Transact(opts, "transferOwnership", to) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.TransferOwnership(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, to) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) TransferOwnership(to common.Address) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.TransferOwnership(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, to) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) WithdrawLink(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.Transact(opts, "withdrawLink", amount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) WithdrawLink(amount *big.Int) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.WithdrawLink(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, amount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) WithdrawLink(amount *big.Int) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.WithdrawLink(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, amount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) WithdrawNative(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.Transact(opts, "withdrawNative", amount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) WithdrawNative(amount *big.Int) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.WithdrawNative(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, amount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) WithdrawNative(amount *big.Int) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.WithdrawNative(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts, amount) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.contract.RawTransact(opts, nil) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerSession) Receive() (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.Receive(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts) +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerTransactorSession) Receive() (*types.Transaction, error) { + return _VRFV2PlusWrapperLoadTestConsumer.Contract.Receive(&_VRFV2PlusWrapperLoadTestConsumer.TransactOpts) +} + +type VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequestedIterator struct { + Event *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequestedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequestedIterator) Error() error { + return it.fail +} + +func (it *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequestedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequestedIterator, 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 := _VRFV2PlusWrapperLoadTestConsumer.contract.FilterLogs(opts, "OwnershipTransferRequested", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequestedIterator{contract: _VRFV2PlusWrapperLoadTestConsumer.contract, event: "OwnershipTransferRequested", logs: logs, sub: sub}, nil +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested, 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 := _VRFV2PlusWrapperLoadTestConsumer.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(VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested) + if err := _VRFV2PlusWrapperLoadTestConsumer.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 (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) ParseOwnershipTransferRequested(log types.Log) (*VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested, error) { + event := new(VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested) + if err := _VRFV2PlusWrapperLoadTestConsumer.contract.UnpackLog(event, "OwnershipTransferRequested", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFV2PlusWrapperLoadTestConsumerOwnershipTransferredIterator struct { + Event *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferredIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferredIterator) Error() error { + return it.fail +} + +func (it *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred struct { + From common.Address + To common.Address + Raw types.Log +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2PlusWrapperLoadTestConsumerOwnershipTransferredIterator, 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 := _VRFV2PlusWrapperLoadTestConsumer.contract.FilterLogs(opts, "OwnershipTransferred", fromRule, toRule) + if err != nil { + return nil, err + } + return &VRFV2PlusWrapperLoadTestConsumerOwnershipTransferredIterator{contract: _VRFV2PlusWrapperLoadTestConsumer.contract, event: "OwnershipTransferred", logs: logs, sub: sub}, nil +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred, 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 := _VRFV2PlusWrapperLoadTestConsumer.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(VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred) + if err := _VRFV2PlusWrapperLoadTestConsumer.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 (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) ParseOwnershipTransferred(log types.Log) (*VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred, error) { + event := new(VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred) + if err := _VRFV2PlusWrapperLoadTestConsumer.contract.UnpackLog(event, "OwnershipTransferred", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilledIterator struct { + Event *VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilledIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilledIterator) Error() error { + return it.fail +} + +func (it *VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilledIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled struct { + RequestId *big.Int + RandomWords []*big.Int + Payment *big.Int + Raw types.Log +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) FilterWrappedRequestFulfilled(opts *bind.FilterOpts) (*VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilledIterator, error) { + + logs, sub, err := _VRFV2PlusWrapperLoadTestConsumer.contract.FilterLogs(opts, "WrappedRequestFulfilled") + if err != nil { + return nil, err + } + return &VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilledIterator{contract: _VRFV2PlusWrapperLoadTestConsumer.contract, event: "WrappedRequestFulfilled", logs: logs, sub: sub}, nil +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) WatchWrappedRequestFulfilled(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled) (event.Subscription, error) { + + logs, sub, err := _VRFV2PlusWrapperLoadTestConsumer.contract.WatchLogs(opts, "WrappedRequestFulfilled") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled) + if err := _VRFV2PlusWrapperLoadTestConsumer.contract.UnpackLog(event, "WrappedRequestFulfilled", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) ParseWrappedRequestFulfilled(log types.Log) (*VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled, error) { + event := new(VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled) + if err := _VRFV2PlusWrapperLoadTestConsumer.contract.UnpackLog(event, "WrappedRequestFulfilled", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type VRFV2PlusWrapperLoadTestConsumerWrapperRequestMadeIterator struct { + Event *VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFV2PlusWrapperLoadTestConsumerWrapperRequestMadeIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFV2PlusWrapperLoadTestConsumerWrapperRequestMadeIterator) Error() error { + return it.fail +} + +func (it *VRFV2PlusWrapperLoadTestConsumerWrapperRequestMadeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade struct { + RequestId *big.Int + Paid *big.Int + Raw types.Log +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) FilterWrapperRequestMade(opts *bind.FilterOpts, requestId []*big.Int) (*VRFV2PlusWrapperLoadTestConsumerWrapperRequestMadeIterator, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + logs, sub, err := _VRFV2PlusWrapperLoadTestConsumer.contract.FilterLogs(opts, "WrapperRequestMade", requestIdRule) + if err != nil { + return nil, err + } + return &VRFV2PlusWrapperLoadTestConsumerWrapperRequestMadeIterator{contract: _VRFV2PlusWrapperLoadTestConsumer.contract, event: "WrapperRequestMade", logs: logs, sub: sub}, nil +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) WatchWrapperRequestMade(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade, requestId []*big.Int) (event.Subscription, error) { + + var requestIdRule []interface{} + for _, requestIdItem := range requestId { + requestIdRule = append(requestIdRule, requestIdItem) + } + + logs, sub, err := _VRFV2PlusWrapperLoadTestConsumer.contract.WatchLogs(opts, "WrapperRequestMade", 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(VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade) + if err := _VRFV2PlusWrapperLoadTestConsumer.contract.UnpackLog(event, "WrapperRequestMade", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumerFilterer) ParseWrapperRequestMade(log types.Log) (*VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade, error) { + event := new(VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade) + if err := _VRFV2PlusWrapperLoadTestConsumer.contract.UnpackLog(event, "WrapperRequestMade", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type GetRequestStatus struct { + Paid *big.Int + Fulfilled bool + RandomWords []*big.Int + RequestTimestamp *big.Int + FulfilmentTimestamp *big.Int + RequestBlockNumber *big.Int + FulfilmentBlockNumber *big.Int +} +type SRequests struct { + Paid *big.Int + Fulfilled bool + RequestTimestamp *big.Int + FulfilmentTimestamp *big.Int + RequestBlockNumber *big.Int + FulfilmentBlockNumber *big.Int + Native bool +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumer) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _VRFV2PlusWrapperLoadTestConsumer.abi.Events["OwnershipTransferRequested"].ID: + return _VRFV2PlusWrapperLoadTestConsumer.ParseOwnershipTransferRequested(log) + case _VRFV2PlusWrapperLoadTestConsumer.abi.Events["OwnershipTransferred"].ID: + return _VRFV2PlusWrapperLoadTestConsumer.ParseOwnershipTransferred(log) + case _VRFV2PlusWrapperLoadTestConsumer.abi.Events["WrappedRequestFulfilled"].ID: + return _VRFV2PlusWrapperLoadTestConsumer.ParseWrappedRequestFulfilled(log) + case _VRFV2PlusWrapperLoadTestConsumer.abi.Events["WrapperRequestMade"].ID: + return _VRFV2PlusWrapperLoadTestConsumer.ParseWrapperRequestMade(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested) Topic() common.Hash { + return common.HexToHash("0xed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae1278") +} + +func (VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred) Topic() common.Hash { + return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") +} + +func (VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled) Topic() common.Hash { + return common.HexToHash("0x6c84e12b4c188e61f1b4727024a5cf05c025fa58467e5eedf763c0744c89da7b") +} + +func (VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade) Topic() common.Hash { + return common.HexToHash("0x5f56b4c20db9f5b294cbf6f681368de4a992a27e2de2ee702dcf2cbbfa791ec4") +} + +func (_VRFV2PlusWrapperLoadTestConsumer *VRFV2PlusWrapperLoadTestConsumer) Address() common.Address { + return _VRFV2PlusWrapperLoadTestConsumer.address +} + +type VRFV2PlusWrapperLoadTestConsumerInterface interface { + GetBalance(opts *bind.CallOpts) (*big.Int, error) + + GetRequestStatus(opts *bind.CallOpts, _requestId *big.Int) (GetRequestStatus, + + error) + + GetWrapper(opts *bind.CallOpts) (common.Address, 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) + + AcceptOwnership(opts *bind.TransactOpts) (*types.Transaction, error) + + MakeRequests(opts *bind.TransactOpts, _callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32, _requestCount uint16) (*types.Transaction, error) + + MakeRequestsNative(opts *bind.TransactOpts, _callbackGasLimit uint32, _requestConfirmations uint16, _numWords uint32, _requestCount uint16) (*types.Transaction, error) + + RawFulfillRandomWords(opts *bind.TransactOpts, _requestId *big.Int, _randomWords []*big.Int) (*types.Transaction, error) + + Reset(opts *bind.TransactOpts) (*types.Transaction, error) + + SetLinkToken(opts *bind.TransactOpts, _link common.Address) (*types.Transaction, error) + + TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) + + WithdrawLink(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + WithdrawNative(opts *bind.TransactOpts, amount *big.Int) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterOwnershipTransferRequested(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequestedIterator, error) + + WatchOwnershipTransferRequested(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferRequested(log types.Log) (*VRFV2PlusWrapperLoadTestConsumerOwnershipTransferRequested, error) + + FilterOwnershipTransferred(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*VRFV2PlusWrapperLoadTestConsumerOwnershipTransferredIterator, error) + + WatchOwnershipTransferred(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseOwnershipTransferred(log types.Log) (*VRFV2PlusWrapperLoadTestConsumerOwnershipTransferred, error) + + FilterWrappedRequestFulfilled(opts *bind.FilterOpts) (*VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilledIterator, error) + + WatchWrappedRequestFulfilled(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled) (event.Subscription, error) + + ParseWrappedRequestFulfilled(log types.Log) (*VRFV2PlusWrapperLoadTestConsumerWrappedRequestFulfilled, error) + + FilterWrapperRequestMade(opts *bind.FilterOpts, requestId []*big.Int) (*VRFV2PlusWrapperLoadTestConsumerWrapperRequestMadeIterator, error) + + WatchWrapperRequestMade(opts *bind.WatchOpts, sink chan<- *VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade, requestId []*big.Int) (event.Subscription, error) + + ParseWrapperRequestMade(log types.Log) (*VRFV2PlusWrapperLoadTestConsumerWrapperRequestMade, error) + + ParseLog(log types.Log) (generated.AbigenLog, error) + + Address() common.Address +} 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 cbbcdf47f5..83ba96ec3a 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -8,7 +8,7 @@ automation_forwarder_logic: ../../contracts/solc/v0.8.16/AutomationForwarderLogi 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 331bfa79685aee6ddf63b64c0747abee556c454cae3fb8175edff425b615d8aa bank_erc20: ../../contracts/solc/v0.8.15/BankERC20.abi ../../contracts/solc/v0.8.15/BankERC20.bin 544cd578927f8e4f3259c01f79e448760f0110b46bb023686f00453960bc2f4e -batch_blockhash_store: ../../contracts/solc/v0.8.6/BatchBlockhashStore.abi ../../contracts/solc/v0.8.6/BatchBlockhashStore.bin c5ab26709a01050402615659403f32d5cd1b85f3ad6bb6bfe021692f4233cf19 +batch_blockhash_store: ../../contracts/solc/v0.8.6/BatchBlockhashStore.abi ../../contracts/solc/v0.8.6/BatchBlockhashStore.bin 14356c48ef70f66ef74f22f644450dbf3b2a147c1b68deaa7e7d1eb8ffab15db batch_vrf_coordinator_v2: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2.bin d0a54963260d8c1f1bbd984b758285e6027cfb5a7e42701bcb562ab123219332 batch_vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus.bin 7bb76ae241cf1b37b41920830b836cb99f1ad33efd7435ca2398ff6cd2fe5d48 blockhash_store: ../../contracts/solc/v0.6/BlockhashStore.abi ../../contracts/solc/v0.6/BlockhashStore.bin a0dc60bcc4bf071033d23fddf7ae936c6a4d1dd81488434b7e24b7aa1fabc37c @@ -47,7 +47,7 @@ mock_aggregator_proxy: ../../contracts/solc/v0.8.6/MockAggregatorProxy.abi ../.. 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 multiwordconsumer_wrapper: ../../contracts/solc/v0.7/MultiWordConsumer.abi ../../contracts/solc/v0.7/MultiWordConsumer.bin 6e68abdf614e3ed0f5066c1b5f9d7c1199f1e7c5c5251fe8a471344a59afc6ba -offchain_aggregator_wrapper: OffchainAggregator/OffchainAggregator.abi - 5f97dc197fd4e2b999856b9b3fa7c2aaf0c700c71d7009d7d017d233bc855877 +offchain_aggregator_wrapper: OffchainAggregator/OffchainAggregator.abi - 5c8d6562e94166d4790f1ee6e4321d359d9f7262e6c5452a712b1f1c896f45cf operator_factory: ../../contracts/solc/v0.7/OperatorFactory.abi ../../contracts/solc/v0.7/OperatorFactory.bin 0bbac9ac2e45f988b8365a83a36dff97534c14d315ebe5a1fc725d87f00c15d5 operator_wrapper: ../../contracts/solc/v0.7/Operator.abi ../../contracts/solc/v0.7/Operator.bin 45036dc5046de66ba03f57b48ef8b629700e863af388cb509b2fa259989762e8 oracle_wrapper: ../../contracts/solc/v0.6/Oracle.abi ../../contracts/solc/v0.6/Oracle.bin 7af2fbac22a6e8c2847e8e685a5400cac5101d72ddf5365213beb79e4dede43a @@ -62,7 +62,7 @@ solidity_vrf_wrapper: ../../contracts/solc/v0.6/VRF.abi ../../contracts/solc/v0. streams_lookup_compatible_interface: ../../contracts/solc/v0.8.16/StreamsLookupCompatibleInterface.abi ../../contracts/solc/v0.8.16/StreamsLookupCompatibleInterface.bin feb92cc666df21ea04ab9d7a588a513847b01b2f66fc167d06ab28ef2b17e015 streams_lookup_upkeep_wrapper: ../../contracts/solc/v0.8.16/StreamsLookupUpkeep.abi ../../contracts/solc/v0.8.16/StreamsLookupUpkeep.bin b1a598963cacac51ed4706538d0f142bdc0d94b9a4b13e2d402131cdf05c9bcf 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 34e71c5dc94f50e21f2bef76b0daa5821634655ca3722ce1204ce43cca1b2e19 +trusted_blockhash_store: ../../contracts/solc/v0.8.6/TrustedBlockhashStore.abi ../../contracts/solc/v0.8.6/TrustedBlockhashStore.bin 98cb0dc06c15af5dcd3b53bdfc98e7ed2489edc96a42203294ac2fc0efdda02b 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 @@ -74,32 +74,35 @@ vrf_consumer_v2: ../../contracts/solc/v0.8.6/VRFConsumerV2.abi ../../contracts/s 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 906e8155db28513c64c6f828d5b8eaf586b873de4369c77c0a19b6c5adf623c1 -vrf_coordinator_v2_plus_v2_example: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.bin 50d881ecf2551c0e56b84cb932f068b703b38b00c73eb05d4e4b80754ecf6b6d +vrf_coordinator_v2: ../../contracts/solc/v0.8.6/VRFCoordinatorV2.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2.bin 6ab95dcdf48951b07698abfc53be56c1b571110fcb2b8f72df1256db091a5f0a +vrf_coordinator_v2_5: ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5.bin 37ad0cc55dcc417c62de7b798defc17910dd1eda6738f755572189b8134a8b74 +vrf_coordinator_v2_plus_v2_example: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus_V2Example.bin 4a5b86701983b1b65f0a8dfa116b3f6d75f8f706fa274004b57bdf5992e4cec3 vrf_coordinator_v2plus: ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.bin e4409bbe361258273458a5c99408b3d7f0cc57a2560dee91c0596cc6d6f738be +vrf_coordinator_v2plus_interface: ../../contracts/solc/v0.8.6/IVRFCoordinatorV2PlusInternal.abi ../../contracts/solc/v0.8.6/IVRFCoordinatorV2PlusInternal.bin 834a2ce0e83276372a0e1446593fd89798f4cf6dc95d4be0113e99fadf61558b 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 -vrf_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics.bin 6c8f08fe8ae9254ae0607dffa5faf2d554488850aa788795b0445938488ad9ce +vrf_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2LoadTestWithMetrics.bin 8ab9de5816fbdf93a2865e2711b85a39a6fc9c413a4b336578c485be1158d430 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 9cfe6f12a086b459f1b841aa21144367a146bbaec3e850a6cd10ba0f1b141a71 +vrf_malicious_consumer_v2_plus: ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus.abi ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus.bin f8d8cd2a9287f7f98541027cfdddeea209c5a17184ee37204181c97897a52c41 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_owner_test_consumer: ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer.bin 0537bbe96c5a8bbd44d0a65fbb7e51f6a9f9e75f4673225845ac1ba33f4e7974 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_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics.bin d880273009b88832eac6a83339e7dd0ac81a3f9ff9d601ce06efee7a8fa32cdb -vrf_v2plus_single_consumer: ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample.bin 5f05457ad1ece35b7cd5730bb2dee6c349484bfc58aefc61d643d1409b17f22b -vrf_v2plus_sub_owner: ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample.bin 42e3aa5421a4898ad3eef1d5ec472d22a1ace259237263e4df582114d4437d0a -vrf_v2plus_upgraded_version: ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion.bin 44bf27a0a9044e95be7c5467ede40ec5bb647f5e0bcbe82c27b252fb650b9265 +vrf_v2plus_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics.bin 0a89cb7ed9dfb42f91e559b03dc351ccdbe14d281a7ab71c63bd3f47eeed7711 +vrf_v2plus_single_consumer: ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample.bin e2aa4cfef91b1d1869ec1f517b4d41049884e0e25345384c2fccbe08cda3e603 +vrf_v2plus_sub_owner: ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample.bin 8bc4a8b74d302b9a7a37556d3746105f487c4d3555643721748533d01b1ae5a4 +vrf_v2plus_upgraded_version: ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion.bin cb37587e0979a9a668eed8b388dc1d835c9763f699f6b97a77d1c3d35d4f04b6 vrfv2_proxy_admin: ../../contracts/solc/v0.8.6/VRFV2ProxyAdmin.abi ../../contracts/solc/v0.8.6/VRFV2ProxyAdmin.bin 30b6d1af9c4ae05daddda2afdab1877d857ab5321afe3540a01e94d5ded9bcef vrfv2_reverting_example: ../../contracts/solc/v0.8.6/VRFV2RevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2RevertingExample.bin 1ae46f80351d428bd85ba58b9041b2a608a1845300d79a8fed83edf96606de87 vrfv2_transparent_upgradeable_proxy: ../../contracts/solc/v0.8.6/VRFV2TransparentUpgradeableProxy.abi ../../contracts/solc/v0.8.6/VRFV2TransparentUpgradeableProxy.bin 84be44ffac513ef5b009d53846b76d3247ceb9fa0545dec2a0dd11606a915850 -vrfv2_wrapper: ../../contracts/solc/v0.8.6/VRFV2Wrapper.abi ../../contracts/solc/v0.8.6/VRFV2Wrapper.bin ccbacaaf7fa058ced4998a3811ad6af15f1be07db20548b945f7569b99d85cbc +vrfv2_wrapper: ../../contracts/solc/v0.8.6/VRFV2Wrapper.abi ../../contracts/solc/v0.8.6/VRFV2Wrapper.bin 7682891b23b7cae7f79803b662556637c52d295c415fbb0708dbec1e5303c01a 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 bec10896851c433bb5997c96d96d9871b335924a59a8ab07d7062fcbc3992c6e -vrfv2plus_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.bin 4d1b1830b411592c7469e3928ad191fed25afc714f1e9947ccd41a5b528cc0ae +vrfv2plus_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.bin 2c480a6d7955d33a00690fdd943486d95802e48a03f3cc243df314448e4ddb2c vrfv2plus_malicious_migrator: ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.abi ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.bin e5ae923d5fdfa916303cd7150b8474ccd912e14bafe950c6431f6ec94821f642 -vrfv2plus_reverting_example: ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.bin d8f9b537f4f75535e3fca943d5f2d5b891fc63f38eb04e0c219fee28033883ae -vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin d30c6232e24e7f6007bd9e46c23534d8da17fbf332f9dfd6485a476ef1be0af9 +vrfv2plus_reverting_example: ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusRevertingExample.bin 34743ac1dd5e2c9d210b2bd721ebd4dff3c29c548f05582538690dde07773589 +vrfv2plus_wrapper: ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin af73d5757129d4de1d287716ecdc560427904bc2a68b7dace4e6b5ac02539a31 vrfv2plus_wrapper_consumer_example: ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.bin d4ddf86da21b87c013f551b2563ab68712ea9d4724894664d5778f6b124f4e78 +vrfv2plus_wrapper_load_test_consumer: ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer.bin 4e8dcc8f60568aa09cc1adc800a56161f46642edc77768c3efab222a30a0e5ae diff --git a/core/gethwrappers/go_generate.go b/core/gethwrappers/go_generate.go index c439a2aad7..6831fd8995 100644 --- a/core/gethwrappers/go_generate.go +++ b/core/gethwrappers/go_generate.go @@ -106,10 +106,11 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/KeepersVRFConsumer.abi ../../contracts/solc/v0.8.6/KeepersVRFConsumer.bin KeepersVRFConsumer keepers_vrf_consumer // VRF V2Plus +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/IVRFCoordinatorV2PlusInternal.abi ../../contracts/solc/v0.8.6/IVRFCoordinatorV2PlusInternal.bin IVRFCoordinatorV2PlusInternal vrf_coordinator_v2plus_interface //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/BatchVRFCoordinatorV2Plus.bin BatchVRFCoordinatorV2Plus batch_vrf_coordinator_v2plus //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/TrustedBlockhashStore.abi ../../contracts/solc/v0.8.6/TrustedBlockhashStore.bin TrustedBlockhashStore trusted_blockhash_store //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusConsumerExample.bin VRFV2PlusConsumerExample vrfv2plus_consumer_example -//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2Plus.bin VRFCoordinatorV2Plus vrf_coordinator_v2plus +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2_5.bin VRFCoordinatorV2_5 vrf_coordinator_v2_5 //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapper.bin VRFV2PlusWrapper vrfv2plus_wrapper //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperConsumerExample.bin VRFV2PlusWrapperConsumerExample vrfv2plus_wrapper_consumer_example //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus.abi ../../contracts/solc/v0.8.6/VRFMaliciousConsumerV2Plus.bin VRFMaliciousConsumerV2Plus vrf_malicious_consumer_v2_plus @@ -122,6 +123,7 @@ package gethwrappers //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.abi ../../contracts/solc/v0.8.6/VRFV2PlusMaliciousMigrator.bin VRFV2PlusMaliciousMigrator vrfv2plus_malicious_migrator //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics.bin VRFV2PlusLoadTestWithMetrics vrf_v2plus_load_test_with_metrics //go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion.bin VRFCoordinatorV2PlusUpgradedVersion vrf_v2plus_upgraded_version +//go:generate go run ./generation/generate/wrap.go ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer.abi ../../contracts/solc/v0.8.6/VRFV2PlusWrapperLoadTestConsumer.bin VRFV2PlusWrapperLoadTestConsumer vrfv2plus_wrapper_load_test_consumer // 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 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 index 4bb84a770a..abc3b47db2 100644 --- 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 @@ -7,3 +7,4 @@ llo_feeds_test: ../../../contracts/solc/v0.8.16/ExposedVerifier.abi ../../../con reward_manager: ../../../contracts/solc/v0.8.16/RewardManager.abi ../../../contracts/solc/v0.8.16/RewardManager.bin db73e9062b17a1d5aa14c06881fe2be49bd95b00b7f1a8943910c5e4ded5b221 verifier: ../../../contracts/solc/v0.8.16/Verifier.abi ../../../contracts/solc/v0.8.16/Verifier.bin df12786bbeccf3a8f3389479cf93c055b4efd5904b9f99a4835f81af43fe62bf verifier_proxy: ../../../contracts/solc/v0.8.16/VerifierProxy.abi ../../../contracts/solc/v0.8.16/VerifierProxy.bin 6393443d0a323f2dbe9687dc30fd77f8dfa918944b61c651759746ff2d76e4e5 +werc20_mock: ../../../contracts/solc/v0.8.19/WERC20Mock.abi ../../../contracts/solc/v0.8.19/WERC20Mock.bin ff2ca3928b2aa9c412c892cb8226c4d754c73eeb291bb7481c32c48791b2aa94 diff --git a/core/gethwrappers/shared/generated/werc20_mock/werc20_mock.go b/core/gethwrappers/shared/generated/werc20_mock/werc20_mock.go new file mode 100644 index 0000000000..3d8660c701 --- /dev/null +++ b/core/gethwrappers/shared/generated/werc20_mock/werc20_mock.go @@ -0,0 +1,1052 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package werc20_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 WERC20MockMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"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\":\"dst\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Deposit\",\"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\":\"src\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"Withdrawal\",\"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\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"burn\",\"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\":[],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"payable\",\"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\":\"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\":\"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\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}]", + Bin: "0x60806040523480156200001157600080fd5b506040518060400160405280600a8152602001695745524332304d6f636b60b01b815250604051806040016040528060048152602001635745524360e01b815250816003908162000063919062000120565b50600462000072828262000120565b505050620001ec565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000a657607f821691505b602082108103620000c757634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200011b57600081815260208120601f850160051c81016020861015620000f65750805b601f850160051c820191505b81811015620001175782815560010162000102565b5050505b505050565b81516001600160401b038111156200013c576200013c6200007b565b62000154816200014d845462000091565b84620000cd565b602080601f8311600181146200018c5760008415620001735750858301515b600019600386901b1c1916600185901b17855562000117565b600085815260208120601f198616915b82811015620001bd578886015182559484019460019091019084016200019c565b5085821015620001dc5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b610fc980620001fc6000396000f3fe6080604052600436106100ec5760003560e01c806340c10f191161008a578063a457c2d711610059578063a457c2d71461028e578063a9059cbb146102ae578063d0e30db0146102ce578063dd62ed3e146102d657600080fd5b806340c10f19146101f657806370a082311461021657806395d89b41146102595780639dc29fac1461026e57600080fd5b806323b872dd116100c657806323b872dd1461017a5780632e1a7d4d1461019a578063313ce567146101ba57806339509351146101d657600080fd5b806306fdde0314610100578063095ea7b31461012b57806318160ddd1461015b57600080fd5b366100fb576100f9610329565b005b600080fd5b34801561010c57600080fd5b5061011561036a565b6040516101229190610dc6565b60405180910390f35b34801561013757600080fd5b5061014b610146366004610e5b565b6103fc565b6040519015158152602001610122565b34801561016757600080fd5b506002545b604051908152602001610122565b34801561018657600080fd5b5061014b610195366004610e85565b610416565b3480156101a657600080fd5b506100f96101b5366004610ec1565b61043a565b3480156101c657600080fd5b5060405160128152602001610122565b3480156101e257600080fd5b5061014b6101f1366004610e5b565b6104c6565b34801561020257600080fd5b506100f9610211366004610e5b565b610512565b34801561022257600080fd5b5061016c610231366004610eda565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b34801561026557600080fd5b50610115610520565b34801561027a57600080fd5b506100f9610289366004610e5b565b61052f565b34801561029a57600080fd5b5061014b6102a9366004610e5b565b610539565b3480156102ba57600080fd5b5061014b6102c9366004610e5b565b61060f565b6100f9610329565b3480156102e257600080fd5b5061016c6102f1366004610efc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b610333333461061d565b60405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b60606003805461037990610f2f565b80601f01602080910402602001604051908101604052809291908181526020018280546103a590610f2f565b80156103f25780601f106103c7576101008083540402835291602001916103f2565b820191906000526020600020905b8154815290600101906020018083116103d557829003601f168201915b5050505050905090565b60003361040a818585610710565b60019150505b92915050565b6000336104248582856108c4565b61042f85858561099b565b506001949350505050565b3360009081526020819052604090205481111561045657600080fd5b6104603382610c0a565b604051339082156108fc029083906000818181858888f1935050505015801561048d573d6000803e3d6000fd5b5060405181815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a250565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919061040a908290869061050d908790610f82565b610710565b61051c828261061d565b5050565b60606004805461037990610f2f565b61051c8282610c0a565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610602576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61042f8286868403610710565b60003361040a81858561099b565b73ffffffffffffffffffffffffffffffffffffffff821661069a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105f9565b80600260008282546106ac9190610f82565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff83166107b2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105f9565b73ffffffffffffffffffffffffffffffffffffffff8216610855576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146109955781811015610988576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105f9565b6109958484848403610710565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610a3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105f9565b73ffffffffffffffffffffffffffffffffffffffff8216610ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610b97576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016105f9565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610995565b73ffffffffffffffffffffffffffffffffffffffff8216610cad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610d63576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016105f9565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91016108b7565b600060208083528351808285015260005b81811015610df357858101830151858201604001528201610dd7565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610e5657600080fd5b919050565b60008060408385031215610e6e57600080fd5b610e7783610e32565b946020939093013593505050565b600080600060608486031215610e9a57600080fd5b610ea384610e32565b9250610eb160208501610e32565b9150604084013590509250925092565b600060208284031215610ed357600080fd5b5035919050565b600060208284031215610eec57600080fd5b610ef582610e32565b9392505050565b60008060408385031215610f0f57600080fd5b610f1883610e32565b9150610f2660208401610e32565b90509250929050565b600181811c90821680610f4357607f821691505b602082108103610f7c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b80820180821115610410577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fdfea164736f6c6343000813000a", +} + +var WERC20MockABI = WERC20MockMetaData.ABI + +var WERC20MockBin = WERC20MockMetaData.Bin + +func DeployWERC20Mock(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *WERC20Mock, error) { + parsed, err := WERC20MockMetaData.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(WERC20MockBin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &WERC20Mock{WERC20MockCaller: WERC20MockCaller{contract: contract}, WERC20MockTransactor: WERC20MockTransactor{contract: contract}, WERC20MockFilterer: WERC20MockFilterer{contract: contract}}, nil +} + +type WERC20Mock struct { + address common.Address + abi abi.ABI + WERC20MockCaller + WERC20MockTransactor + WERC20MockFilterer +} + +type WERC20MockCaller struct { + contract *bind.BoundContract +} + +type WERC20MockTransactor struct { + contract *bind.BoundContract +} + +type WERC20MockFilterer struct { + contract *bind.BoundContract +} + +type WERC20MockSession struct { + Contract *WERC20Mock + CallOpts bind.CallOpts + TransactOpts bind.TransactOpts +} + +type WERC20MockCallerSession struct { + Contract *WERC20MockCaller + CallOpts bind.CallOpts +} + +type WERC20MockTransactorSession struct { + Contract *WERC20MockTransactor + TransactOpts bind.TransactOpts +} + +type WERC20MockRaw struct { + Contract *WERC20Mock +} + +type WERC20MockCallerRaw struct { + Contract *WERC20MockCaller +} + +type WERC20MockTransactorRaw struct { + Contract *WERC20MockTransactor +} + +func NewWERC20Mock(address common.Address, backend bind.ContractBackend) (*WERC20Mock, error) { + abi, err := abi.JSON(strings.NewReader(WERC20MockABI)) + if err != nil { + return nil, err + } + contract, err := bindWERC20Mock(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &WERC20Mock{address: address, abi: abi, WERC20MockCaller: WERC20MockCaller{contract: contract}, WERC20MockTransactor: WERC20MockTransactor{contract: contract}, WERC20MockFilterer: WERC20MockFilterer{contract: contract}}, nil +} + +func NewWERC20MockCaller(address common.Address, caller bind.ContractCaller) (*WERC20MockCaller, error) { + contract, err := bindWERC20Mock(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &WERC20MockCaller{contract: contract}, nil +} + +func NewWERC20MockTransactor(address common.Address, transactor bind.ContractTransactor) (*WERC20MockTransactor, error) { + contract, err := bindWERC20Mock(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &WERC20MockTransactor{contract: contract}, nil +} + +func NewWERC20MockFilterer(address common.Address, filterer bind.ContractFilterer) (*WERC20MockFilterer, error) { + contract, err := bindWERC20Mock(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &WERC20MockFilterer{contract: contract}, nil +} + +func bindWERC20Mock(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := WERC20MockMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +func (_WERC20Mock *WERC20MockRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _WERC20Mock.Contract.WERC20MockCaller.contract.Call(opts, result, method, params...) +} + +func (_WERC20Mock *WERC20MockRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WERC20Mock.Contract.WERC20MockTransactor.contract.Transfer(opts) +} + +func (_WERC20Mock *WERC20MockRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _WERC20Mock.Contract.WERC20MockTransactor.contract.Transact(opts, method, params...) +} + +func (_WERC20Mock *WERC20MockCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _WERC20Mock.Contract.contract.Call(opts, result, method, params...) +} + +func (_WERC20Mock *WERC20MockTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WERC20Mock.Contract.contract.Transfer(opts) +} + +func (_WERC20Mock *WERC20MockTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _WERC20Mock.Contract.contract.Transact(opts, method, params...) +} + +func (_WERC20Mock *WERC20MockCaller) Allowance(opts *bind.CallOpts, owner common.Address, spender common.Address) (*big.Int, error) { + var out []interface{} + err := _WERC20Mock.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 (_WERC20Mock *WERC20MockSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _WERC20Mock.Contract.Allowance(&_WERC20Mock.CallOpts, owner, spender) +} + +func (_WERC20Mock *WERC20MockCallerSession) Allowance(owner common.Address, spender common.Address) (*big.Int, error) { + return _WERC20Mock.Contract.Allowance(&_WERC20Mock.CallOpts, owner, spender) +} + +func (_WERC20Mock *WERC20MockCaller) BalanceOf(opts *bind.CallOpts, account common.Address) (*big.Int, error) { + var out []interface{} + err := _WERC20Mock.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 (_WERC20Mock *WERC20MockSession) BalanceOf(account common.Address) (*big.Int, error) { + return _WERC20Mock.Contract.BalanceOf(&_WERC20Mock.CallOpts, account) +} + +func (_WERC20Mock *WERC20MockCallerSession) BalanceOf(account common.Address) (*big.Int, error) { + return _WERC20Mock.Contract.BalanceOf(&_WERC20Mock.CallOpts, account) +} + +func (_WERC20Mock *WERC20MockCaller) Decimals(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _WERC20Mock.contract.Call(opts, &out, "decimals") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +func (_WERC20Mock *WERC20MockSession) Decimals() (uint8, error) { + return _WERC20Mock.Contract.Decimals(&_WERC20Mock.CallOpts) +} + +func (_WERC20Mock *WERC20MockCallerSession) Decimals() (uint8, error) { + return _WERC20Mock.Contract.Decimals(&_WERC20Mock.CallOpts) +} + +func (_WERC20Mock *WERC20MockCaller) Name(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _WERC20Mock.contract.Call(opts, &out, "name") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_WERC20Mock *WERC20MockSession) Name() (string, error) { + return _WERC20Mock.Contract.Name(&_WERC20Mock.CallOpts) +} + +func (_WERC20Mock *WERC20MockCallerSession) Name() (string, error) { + return _WERC20Mock.Contract.Name(&_WERC20Mock.CallOpts) +} + +func (_WERC20Mock *WERC20MockCaller) Symbol(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _WERC20Mock.contract.Call(opts, &out, "symbol") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +func (_WERC20Mock *WERC20MockSession) Symbol() (string, error) { + return _WERC20Mock.Contract.Symbol(&_WERC20Mock.CallOpts) +} + +func (_WERC20Mock *WERC20MockCallerSession) Symbol() (string, error) { + return _WERC20Mock.Contract.Symbol(&_WERC20Mock.CallOpts) +} + +func (_WERC20Mock *WERC20MockCaller) TotalSupply(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _WERC20Mock.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 (_WERC20Mock *WERC20MockSession) TotalSupply() (*big.Int, error) { + return _WERC20Mock.Contract.TotalSupply(&_WERC20Mock.CallOpts) +} + +func (_WERC20Mock *WERC20MockCallerSession) TotalSupply() (*big.Int, error) { + return _WERC20Mock.Contract.TotalSupply(&_WERC20Mock.CallOpts) +} + +func (_WERC20Mock *WERC20MockTransactor) Approve(opts *bind.TransactOpts, spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.contract.Transact(opts, "approve", spender, amount) +} + +func (_WERC20Mock *WERC20MockSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Approve(&_WERC20Mock.TransactOpts, spender, amount) +} + +func (_WERC20Mock *WERC20MockTransactorSession) Approve(spender common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Approve(&_WERC20Mock.TransactOpts, spender, amount) +} + +func (_WERC20Mock *WERC20MockTransactor) Burn(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.contract.Transact(opts, "burn", account, amount) +} + +func (_WERC20Mock *WERC20MockSession) Burn(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Burn(&_WERC20Mock.TransactOpts, account, amount) +} + +func (_WERC20Mock *WERC20MockTransactorSession) Burn(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Burn(&_WERC20Mock.TransactOpts, account, amount) +} + +func (_WERC20Mock *WERC20MockTransactor) DecreaseAllowance(opts *bind.TransactOpts, spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _WERC20Mock.contract.Transact(opts, "decreaseAllowance", spender, subtractedValue) +} + +func (_WERC20Mock *WERC20MockSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.DecreaseAllowance(&_WERC20Mock.TransactOpts, spender, subtractedValue) +} + +func (_WERC20Mock *WERC20MockTransactorSession) DecreaseAllowance(spender common.Address, subtractedValue *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.DecreaseAllowance(&_WERC20Mock.TransactOpts, spender, subtractedValue) +} + +func (_WERC20Mock *WERC20MockTransactor) Deposit(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WERC20Mock.contract.Transact(opts, "deposit") +} + +func (_WERC20Mock *WERC20MockSession) Deposit() (*types.Transaction, error) { + return _WERC20Mock.Contract.Deposit(&_WERC20Mock.TransactOpts) +} + +func (_WERC20Mock *WERC20MockTransactorSession) Deposit() (*types.Transaction, error) { + return _WERC20Mock.Contract.Deposit(&_WERC20Mock.TransactOpts) +} + +func (_WERC20Mock *WERC20MockTransactor) IncreaseAllowance(opts *bind.TransactOpts, spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _WERC20Mock.contract.Transact(opts, "increaseAllowance", spender, addedValue) +} + +func (_WERC20Mock *WERC20MockSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.IncreaseAllowance(&_WERC20Mock.TransactOpts, spender, addedValue) +} + +func (_WERC20Mock *WERC20MockTransactorSession) IncreaseAllowance(spender common.Address, addedValue *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.IncreaseAllowance(&_WERC20Mock.TransactOpts, spender, addedValue) +} + +func (_WERC20Mock *WERC20MockTransactor) Mint(opts *bind.TransactOpts, account common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.contract.Transact(opts, "mint", account, amount) +} + +func (_WERC20Mock *WERC20MockSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Mint(&_WERC20Mock.TransactOpts, account, amount) +} + +func (_WERC20Mock *WERC20MockTransactorSession) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Mint(&_WERC20Mock.TransactOpts, account, amount) +} + +func (_WERC20Mock *WERC20MockTransactor) Transfer(opts *bind.TransactOpts, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.contract.Transact(opts, "transfer", to, amount) +} + +func (_WERC20Mock *WERC20MockSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Transfer(&_WERC20Mock.TransactOpts, to, amount) +} + +func (_WERC20Mock *WERC20MockTransactorSession) Transfer(to common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Transfer(&_WERC20Mock.TransactOpts, to, amount) +} + +func (_WERC20Mock *WERC20MockTransactor) TransferFrom(opts *bind.TransactOpts, from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.contract.Transact(opts, "transferFrom", from, to, amount) +} + +func (_WERC20Mock *WERC20MockSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.TransferFrom(&_WERC20Mock.TransactOpts, from, to, amount) +} + +func (_WERC20Mock *WERC20MockTransactorSession) TransferFrom(from common.Address, to common.Address, amount *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.TransferFrom(&_WERC20Mock.TransactOpts, from, to, amount) +} + +func (_WERC20Mock *WERC20MockTransactor) Withdraw(opts *bind.TransactOpts, wad *big.Int) (*types.Transaction, error) { + return _WERC20Mock.contract.Transact(opts, "withdraw", wad) +} + +func (_WERC20Mock *WERC20MockSession) Withdraw(wad *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Withdraw(&_WERC20Mock.TransactOpts, wad) +} + +func (_WERC20Mock *WERC20MockTransactorSession) Withdraw(wad *big.Int) (*types.Transaction, error) { + return _WERC20Mock.Contract.Withdraw(&_WERC20Mock.TransactOpts, wad) +} + +func (_WERC20Mock *WERC20MockTransactor) Receive(opts *bind.TransactOpts) (*types.Transaction, error) { + return _WERC20Mock.contract.RawTransact(opts, nil) +} + +func (_WERC20Mock *WERC20MockSession) Receive() (*types.Transaction, error) { + return _WERC20Mock.Contract.Receive(&_WERC20Mock.TransactOpts) +} + +func (_WERC20Mock *WERC20MockTransactorSession) Receive() (*types.Transaction, error) { + return _WERC20Mock.Contract.Receive(&_WERC20Mock.TransactOpts) +} + +type WERC20MockApprovalIterator struct { + Event *WERC20MockApproval + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WERC20MockApprovalIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WERC20MockApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(WERC20MockApproval) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *WERC20MockApprovalIterator) Error() error { + return it.fail +} + +func (it *WERC20MockApprovalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WERC20MockApproval struct { + Owner common.Address + Spender common.Address + Value *big.Int + Raw types.Log +} + +func (_WERC20Mock *WERC20MockFilterer) FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*WERC20MockApprovalIterator, 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 := _WERC20Mock.contract.FilterLogs(opts, "Approval", ownerRule, spenderRule) + if err != nil { + return nil, err + } + return &WERC20MockApprovalIterator{contract: _WERC20Mock.contract, event: "Approval", logs: logs, sub: sub}, nil +} + +func (_WERC20Mock *WERC20MockFilterer) WatchApproval(opts *bind.WatchOpts, sink chan<- *WERC20MockApproval, 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 := _WERC20Mock.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(WERC20MockApproval) + if err := _WERC20Mock.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 (_WERC20Mock *WERC20MockFilterer) ParseApproval(log types.Log) (*WERC20MockApproval, error) { + event := new(WERC20MockApproval) + if err := _WERC20Mock.contract.UnpackLog(event, "Approval", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type WERC20MockDepositIterator struct { + Event *WERC20MockDeposit + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WERC20MockDepositIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WERC20MockDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(WERC20MockDeposit) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *WERC20MockDepositIterator) Error() error { + return it.fail +} + +func (it *WERC20MockDepositIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WERC20MockDeposit struct { + Dst common.Address + Wad *big.Int + Raw types.Log +} + +func (_WERC20Mock *WERC20MockFilterer) FilterDeposit(opts *bind.FilterOpts, dst []common.Address) (*WERC20MockDepositIterator, error) { + + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WERC20Mock.contract.FilterLogs(opts, "Deposit", dstRule) + if err != nil { + return nil, err + } + return &WERC20MockDepositIterator{contract: _WERC20Mock.contract, event: "Deposit", logs: logs, sub: sub}, nil +} + +func (_WERC20Mock *WERC20MockFilterer) WatchDeposit(opts *bind.WatchOpts, sink chan<- *WERC20MockDeposit, dst []common.Address) (event.Subscription, error) { + + var dstRule []interface{} + for _, dstItem := range dst { + dstRule = append(dstRule, dstItem) + } + + logs, sub, err := _WERC20Mock.contract.WatchLogs(opts, "Deposit", dstRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WERC20MockDeposit) + if err := _WERC20Mock.contract.UnpackLog(event, "Deposit", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_WERC20Mock *WERC20MockFilterer) ParseDeposit(log types.Log) (*WERC20MockDeposit, error) { + event := new(WERC20MockDeposit) + if err := _WERC20Mock.contract.UnpackLog(event, "Deposit", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type WERC20MockTransferIterator struct { + Event *WERC20MockTransfer + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WERC20MockTransferIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WERC20MockTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(WERC20MockTransfer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *WERC20MockTransferIterator) Error() error { + return it.fail +} + +func (it *WERC20MockTransferIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WERC20MockTransfer struct { + From common.Address + To common.Address + Value *big.Int + Raw types.Log +} + +func (_WERC20Mock *WERC20MockFilterer) FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*WERC20MockTransferIterator, 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 := _WERC20Mock.contract.FilterLogs(opts, "Transfer", fromRule, toRule) + if err != nil { + return nil, err + } + return &WERC20MockTransferIterator{contract: _WERC20Mock.contract, event: "Transfer", logs: logs, sub: sub}, nil +} + +func (_WERC20Mock *WERC20MockFilterer) WatchTransfer(opts *bind.WatchOpts, sink chan<- *WERC20MockTransfer, 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 := _WERC20Mock.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(WERC20MockTransfer) + if err := _WERC20Mock.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 (_WERC20Mock *WERC20MockFilterer) ParseTransfer(log types.Log) (*WERC20MockTransfer, error) { + event := new(WERC20MockTransfer) + if err := _WERC20Mock.contract.UnpackLog(event, "Transfer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type WERC20MockWithdrawalIterator struct { + Event *WERC20MockWithdrawal + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *WERC20MockWithdrawalIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(WERC20MockWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(WERC20MockWithdrawal) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *WERC20MockWithdrawalIterator) Error() error { + return it.fail +} + +func (it *WERC20MockWithdrawalIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type WERC20MockWithdrawal struct { + Src common.Address + Wad *big.Int + Raw types.Log +} + +func (_WERC20Mock *WERC20MockFilterer) FilterWithdrawal(opts *bind.FilterOpts, src []common.Address) (*WERC20MockWithdrawalIterator, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _WERC20Mock.contract.FilterLogs(opts, "Withdrawal", srcRule) + if err != nil { + return nil, err + } + return &WERC20MockWithdrawalIterator{contract: _WERC20Mock.contract, event: "Withdrawal", logs: logs, sub: sub}, nil +} + +func (_WERC20Mock *WERC20MockFilterer) WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *WERC20MockWithdrawal, src []common.Address) (event.Subscription, error) { + + var srcRule []interface{} + for _, srcItem := range src { + srcRule = append(srcRule, srcItem) + } + + logs, sub, err := _WERC20Mock.contract.WatchLogs(opts, "Withdrawal", srcRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(WERC20MockWithdrawal) + if err := _WERC20Mock.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_WERC20Mock *WERC20MockFilterer) ParseWithdrawal(log types.Log) (*WERC20MockWithdrawal, error) { + event := new(WERC20MockWithdrawal) + if err := _WERC20Mock.contract.UnpackLog(event, "Withdrawal", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +func (_WERC20Mock *WERC20Mock) ParseLog(log types.Log) (generated.AbigenLog, error) { + switch log.Topics[0] { + case _WERC20Mock.abi.Events["Approval"].ID: + return _WERC20Mock.ParseApproval(log) + case _WERC20Mock.abi.Events["Deposit"].ID: + return _WERC20Mock.ParseDeposit(log) + case _WERC20Mock.abi.Events["Transfer"].ID: + return _WERC20Mock.ParseTransfer(log) + case _WERC20Mock.abi.Events["Withdrawal"].ID: + return _WERC20Mock.ParseWithdrawal(log) + + default: + return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) + } +} + +func (WERC20MockApproval) Topic() common.Hash { + return common.HexToHash("0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925") +} + +func (WERC20MockDeposit) Topic() common.Hash { + return common.HexToHash("0xe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c") +} + +func (WERC20MockTransfer) Topic() common.Hash { + return common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef") +} + +func (WERC20MockWithdrawal) Topic() common.Hash { + return common.HexToHash("0x7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65") +} + +func (_WERC20Mock *WERC20Mock) Address() common.Address { + return _WERC20Mock.address +} + +type WERC20MockInterface 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) + + Burn(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) + + Deposit(opts *bind.TransactOpts) (*types.Transaction, error) + + IncreaseAllowance(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) + + 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) + + Withdraw(opts *bind.TransactOpts, wad *big.Int) (*types.Transaction, error) + + Receive(opts *bind.TransactOpts) (*types.Transaction, error) + + FilterApproval(opts *bind.FilterOpts, owner []common.Address, spender []common.Address) (*WERC20MockApprovalIterator, error) + + WatchApproval(opts *bind.WatchOpts, sink chan<- *WERC20MockApproval, owner []common.Address, spender []common.Address) (event.Subscription, error) + + ParseApproval(log types.Log) (*WERC20MockApproval, error) + + FilterDeposit(opts *bind.FilterOpts, dst []common.Address) (*WERC20MockDepositIterator, error) + + WatchDeposit(opts *bind.WatchOpts, sink chan<- *WERC20MockDeposit, dst []common.Address) (event.Subscription, error) + + ParseDeposit(log types.Log) (*WERC20MockDeposit, error) + + FilterTransfer(opts *bind.FilterOpts, from []common.Address, to []common.Address) (*WERC20MockTransferIterator, error) + + WatchTransfer(opts *bind.WatchOpts, sink chan<- *WERC20MockTransfer, from []common.Address, to []common.Address) (event.Subscription, error) + + ParseTransfer(log types.Log) (*WERC20MockTransfer, error) + + FilterWithdrawal(opts *bind.FilterOpts, src []common.Address) (*WERC20MockWithdrawalIterator, error) + + WatchWithdrawal(opts *bind.WatchOpts, sink chan<- *WERC20MockWithdrawal, src []common.Address) (event.Subscription, error) + + ParseWithdrawal(log types.Log) (*WERC20MockWithdrawal, 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 index 3094b1a94f..7ac7e77a4b 100644 --- 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 @@ -2,3 +2,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 +werc20_mock: ../../../contracts/solc/v0.8.19/WERC20Mock.abi ../../../contracts/solc/v0.8.19/WERC20Mock.bin ff2ca3928b2aa9c412c892cb8226c4d754c73eeb291bb7481c32c48791b2aa94 diff --git a/core/gethwrappers/shared/go_generate.go b/core/gethwrappers/shared/go_generate.go index 169a87b9b2..85a01670c9 100644 --- a/core/gethwrappers/shared/go_generate.go +++ b/core/gethwrappers/shared/go_generate.go @@ -5,3 +5,4 @@ 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 +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.19/WERC20Mock.abi ../../../contracts/solc/v0.8.19/WERC20Mock.bin WERC20Mock werc20_mock diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 1c5d1ed5bb..671d407281 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -386,17 +386,16 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn relayerFactory := chainlink.RelayerFactory{ Logger: lggr, - DB: db, - QConfig: cfg.Database(), LoopRegistry: loopRegistry, GRPCOpts: loop.GRPCOpts{}, } evmOpts := chainlink.EVMFactoryConfig{ - RelayerConfig: &evm.RelayerConfig{ + ChainOpts: evm.ChainOpts{ AppConfig: cfg, EventBroadcaster: eventBroadcaster, MailMon: mailMon, + DB: db, }, CSAETHKeystore: keyStore, } @@ -423,6 +422,8 @@ func NewApplicationWithConfig(t testing.TB, cfg chainlink.GeneralConfig, flagsAn Keystore: keyStore.Cosmos(), CosmosConfigs: cfg.CosmosConfigs(), EventBroadcaster: eventBroadcaster, + DB: db, + QConfig: cfg.Database(), } initOps = append(initOps, chainlink.InitCosmos(testCtx, relayerFactory, cosmosCfg)) } diff --git a/core/internal/cltest/heavyweight/orm.go b/core/internal/cltest/heavyweight/orm.go index 3690a986e2..841901c25a 100644 --- a/core/internal/cltest/heavyweight/orm.go +++ b/core/internal/cltest/heavyweight/orm.go @@ -29,21 +29,21 @@ import ( // FullTestDBV2 creates a pristine DB which runs in a separate database than the normal // unit tests, so you can do things like use other Postgres connection types with it. -func FullTestDBV2(t *testing.T, name string, overrideFn func(c *chainlink.Config, s *chainlink.Secrets)) (chainlink.GeneralConfig, *sqlx.DB) { +func FullTestDBV2(t testing.TB, name string, overrideFn func(c *chainlink.Config, s *chainlink.Secrets)) (chainlink.GeneralConfig, *sqlx.DB) { return prepareFullTestDBV2(t, name, false, true, overrideFn) } // FullTestDBNoFixturesV2 is the same as FullTestDB, but it does not load fixtures. -func FullTestDBNoFixturesV2(t *testing.T, name string, overrideFn func(c *chainlink.Config, s *chainlink.Secrets)) (chainlink.GeneralConfig, *sqlx.DB) { +func FullTestDBNoFixturesV2(t testing.TB, name string, overrideFn func(c *chainlink.Config, s *chainlink.Secrets)) (chainlink.GeneralConfig, *sqlx.DB) { return prepareFullTestDBV2(t, name, false, false, overrideFn) } // FullTestDBEmptyV2 creates an empty DB (without migrations). -func FullTestDBEmptyV2(t *testing.T, name string, overrideFn func(c *chainlink.Config, s *chainlink.Secrets)) (chainlink.GeneralConfig, *sqlx.DB) { +func FullTestDBEmptyV2(t testing.TB, name string, overrideFn func(c *chainlink.Config, s *chainlink.Secrets)) (chainlink.GeneralConfig, *sqlx.DB) { return prepareFullTestDBV2(t, name, true, false, overrideFn) } -func prepareFullTestDBV2(t *testing.T, name string, empty bool, loadFixtures bool, overrideFn func(c *chainlink.Config, s *chainlink.Secrets)) (chainlink.GeneralConfig, *sqlx.DB) { +func prepareFullTestDBV2(t testing.TB, name string, empty bool, loadFixtures bool, overrideFn func(c *chainlink.Config, s *chainlink.Secrets)) (chainlink.GeneralConfig, *sqlx.DB) { testutils.SkipShort(t, "FullTestDB") if empty && loadFixtures { diff --git a/core/internal/cltest/mocks.go b/core/internal/cltest/mocks.go index 439ca2b721..9fdbcbb373 100644 --- a/core/internal/cltest/mocks.go +++ b/core/internal/cltest/mocks.go @@ -27,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 @@ -308,35 +309,16 @@ func MustRandomUser(t testing.TB) sessions.User { return r } -// CreateUserWithRole inserts a new user with specified role and associated test DB email into the test DB -func CreateUserWithRole(t testing.TB, role sessions.UserRole) sessions.User { - email := "" - switch role { - case sessions.UserRoleAdmin: - email = APIEmailAdmin - case sessions.UserRoleEdit: - email = APIEmailEdit - case sessions.UserRoleRun: - email = APIEmailRun - case sessions.UserRoleView: - email = APIEmailViewOnly - default: - t.Fatal("Unexpected role for CreateUserWithRole") - } - - r, err := sessions.NewUser(email, Password, role) - if err != nil { - logger.TestLogger(t).Panic(err) - } - return r -} +func NewUserWithSession(t testing.TB, orm sessions.ORM) sessions.User { + u := MustRandomUser(t) + require.NoError(t, orm.CreateUser(&u)) -func MustNewUser(t *testing.T, email, password string) sessions.User { - r, err := sessions.NewUser(email, password, sessions.UserRoleAdmin) - if err != nil { - t.Fatal(err) - } - return r + _, err := orm.CreateSession(sessions.SessionRequest{ + Email: u.Email, + Password: Password, + }) + require.NoError(t, err) + return u } type MockAPIInitializer struct { diff --git a/core/internal/features/ocr2/features_ocr2_test.go b/core/internal/features/ocr2/features_ocr2_test.go index 82d4fadd70..3883e0319e 100644 --- a/core/internal/features/ocr2/features_ocr2_test.go +++ b/core/internal/features/ocr2/features_ocr2_test.go @@ -24,13 +24,14 @@ import ( "github.com/onsi/gomega" "github.com/smartcontractkit/libocr/commontypes" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - testoffchainaggregator2 "github.com/smartcontractkit/libocr/gethwrappers2/testocr2aggregator" - confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" - ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/exp/maps" + testoffchainaggregator2 "github.com/smartcontractkit/libocr/gethwrappers2/testocr2aggregator" + confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink/v2/core/assets" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/forwarders" @@ -43,6 +44,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "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/testhelpers" "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" @@ -238,12 +240,20 @@ func TestIntegration_OCR2(t *testing.T) { require.NoError(t, err) blockBeforeConfig, err := b.BlockByNumber(testutils.Context(t), nil) require.NoError(t, err) - signers, transmitters, threshold, onchainConfig, encodedConfigVersion, encodedConfig, err := confighelper2.ContractSetConfigArgsForEthereumIntegrationTest( + signers, transmitters, threshold, _, encodedConfigVersion, encodedConfig, err := confighelper2.ContractSetConfigArgsForEthereumIntegrationTest( oracles, 1, 1000000000/100, // threshold PPB ) require.NoError(t, err) + + minAnswer, maxAnswer := new(big.Int), new(big.Int) + minAnswer.Exp(big.NewInt(-2), big.NewInt(191), nil) + maxAnswer.Exp(big.NewInt(2), big.NewInt(191), nil) + maxAnswer.Sub(maxAnswer, big.NewInt(1)) + + onchainConfig, err := testhelpers.GenerateDefaultOCR2OnchainConfig(minAnswer, maxAnswer) + require.NoError(t, err) lggr.Debugw("Setting Config on Oracle Contract", "signers", signers, "transmitters", transmitters, @@ -506,13 +516,21 @@ func TestIntegration_OCR2_ForwarderFlow(t *testing.T) { require.NoError(t, err) blockBeforeConfig, err := b.BlockByNumber(testutils.Context(t), nil) require.NoError(t, err) - signers, effectiveTransmitters, threshold, onchainConfig, encodedConfigVersion, encodedConfig, err := confighelper2.ContractSetConfigArgsForEthereumIntegrationTest( + signers, effectiveTransmitters, threshold, _, encodedConfigVersion, encodedConfig, err := confighelper2.ContractSetConfigArgsForEthereumIntegrationTest( oracles, 1, 1000000000/100, // threshold PPB ) require.NoError(t, err) + minAnswer, maxAnswer := new(big.Int), new(big.Int) + minAnswer.Exp(big.NewInt(-2), big.NewInt(191), nil) + maxAnswer.Exp(big.NewInt(2), big.NewInt(191), nil) + maxAnswer.Sub(maxAnswer, big.NewInt(1)) + + onchainConfig, err := testhelpers.GenerateDefaultOCR2OnchainConfig(minAnswer, maxAnswer) + require.NoError(t, err) + lggr.Debugw("Setting Config on Oracle Contract", "signers", signers, "transmitters", transmitters, diff --git a/core/internal/testutils/evmtest/evmtest.go b/core/internal/testutils/evmtest/evmtest.go index 62696f75d9..2a86101d0d 100644 --- a/core/internal/testutils/evmtest/evmtest.go +++ b/core/internal/testutils/evmtest/evmtest.go @@ -82,13 +82,13 @@ func NewChainRelayExtOpts(t testing.TB, testopts TestChainOpts) evm.ChainRelayEx require.NotNil(t, testopts.KeyStore) opts := evm.ChainRelayExtenderConfig{ Logger: logger.TestLogger(t), - DB: testopts.DB, KeyStore: testopts.KeyStore, - RelayerConfig: &evm.RelayerConfig{ + ChainOpts: evm.ChainOpts{ AppConfig: testopts.GeneralConfig, EventBroadcaster: pg.NewNullEventBroadcaster(), MailMon: testopts.MailMon, GasEstimator: testopts.GasEstimator, + DB: testopts.DB, }, } opts.GenEthClient = func(*big.Int) evmclient.Client { diff --git a/core/logger/logger.go b/core/logger/logger.go index bd6893cbb2..8e847a99ac 100644 --- a/core/logger/logger.go +++ b/core/logger/logger.go @@ -52,6 +52,7 @@ func init() { var _ relaylogger.Logger = (Logger)(nil) //go:generate mockery --quiet --name Logger --output . --filename logger_mock_test.go --inpackage --case=underscore +//go:generate mockery --quiet --name Logger --output ./mocks/ --case=underscore // Logger is the main interface of this package. // It implements uber/zap's SugaredLogger interface and adds conditional logging helpers. diff --git a/core/logger/mocks/logger.go b/core/logger/mocks/logger.go new file mode 100644 index 0000000000..24752c2b6b --- /dev/null +++ b/core/logger/mocks/logger.go @@ -0,0 +1,302 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + logger "github.com/smartcontractkit/chainlink/v2/core/logger" + mock "github.com/stretchr/testify/mock" + + zapcore "go.uber.org/zap/zapcore" +) + +// Logger is an autogenerated mock type for the Logger type +type Logger struct { + mock.Mock +} + +// Critical provides a mock function with given fields: args +func (_m *Logger) Critical(args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// Criticalf provides a mock function with given fields: format, values +func (_m *Logger) Criticalf(format string, values ...interface{}) { + var _ca []interface{} + _ca = append(_ca, format) + _ca = append(_ca, values...) + _m.Called(_ca...) +} + +// Criticalw provides a mock function with given fields: msg, keysAndValues +func (_m *Logger) Criticalw(msg string, keysAndValues ...interface{}) { + var _ca []interface{} + _ca = append(_ca, msg) + _ca = append(_ca, keysAndValues...) + _m.Called(_ca...) +} + +// Debug provides a mock function with given fields: args +func (_m *Logger) Debug(args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// Debugf provides a mock function with given fields: format, values +func (_m *Logger) Debugf(format string, values ...interface{}) { + var _ca []interface{} + _ca = append(_ca, format) + _ca = append(_ca, values...) + _m.Called(_ca...) +} + +// Debugw provides a mock function with given fields: msg, keysAndValues +func (_m *Logger) Debugw(msg string, keysAndValues ...interface{}) { + var _ca []interface{} + _ca = append(_ca, msg) + _ca = append(_ca, keysAndValues...) + _m.Called(_ca...) +} + +// Error provides a mock function with given fields: args +func (_m *Logger) Error(args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// Errorf provides a mock function with given fields: format, values +func (_m *Logger) Errorf(format string, values ...interface{}) { + var _ca []interface{} + _ca = append(_ca, format) + _ca = append(_ca, values...) + _m.Called(_ca...) +} + +// Errorw provides a mock function with given fields: msg, keysAndValues +func (_m *Logger) Errorw(msg string, keysAndValues ...interface{}) { + var _ca []interface{} + _ca = append(_ca, msg) + _ca = append(_ca, keysAndValues...) + _m.Called(_ca...) +} + +// Fatal provides a mock function with given fields: args +func (_m *Logger) Fatal(args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// Fatalf provides a mock function with given fields: format, values +func (_m *Logger) Fatalf(format string, values ...interface{}) { + var _ca []interface{} + _ca = append(_ca, format) + _ca = append(_ca, values...) + _m.Called(_ca...) +} + +// Fatalw provides a mock function with given fields: msg, keysAndValues +func (_m *Logger) Fatalw(msg string, keysAndValues ...interface{}) { + var _ca []interface{} + _ca = append(_ca, msg) + _ca = append(_ca, keysAndValues...) + _m.Called(_ca...) +} + +// Helper provides a mock function with given fields: skip +func (_m *Logger) Helper(skip int) logger.Logger { + ret := _m.Called(skip) + + var r0 logger.Logger + if rf, ok := ret.Get(0).(func(int) logger.Logger); ok { + r0 = rf(skip) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(logger.Logger) + } + } + + return r0 +} + +// Info provides a mock function with given fields: args +func (_m *Logger) Info(args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// Infof provides a mock function with given fields: format, values +func (_m *Logger) Infof(format string, values ...interface{}) { + var _ca []interface{} + _ca = append(_ca, format) + _ca = append(_ca, values...) + _m.Called(_ca...) +} + +// Infow provides a mock function with given fields: msg, keysAndValues +func (_m *Logger) Infow(msg string, keysAndValues ...interface{}) { + var _ca []interface{} + _ca = append(_ca, msg) + _ca = append(_ca, keysAndValues...) + _m.Called(_ca...) +} + +// Name provides a mock function with given fields: +func (_m *Logger) 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 +} + +// Named provides a mock function with given fields: name +func (_m *Logger) Named(name string) logger.Logger { + ret := _m.Called(name) + + var r0 logger.Logger + if rf, ok := ret.Get(0).(func(string) logger.Logger); ok { + r0 = rf(name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(logger.Logger) + } + } + + return r0 +} + +// Panic provides a mock function with given fields: args +func (_m *Logger) Panic(args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// Panicf provides a mock function with given fields: format, values +func (_m *Logger) Panicf(format string, values ...interface{}) { + var _ca []interface{} + _ca = append(_ca, format) + _ca = append(_ca, values...) + _m.Called(_ca...) +} + +// Panicw provides a mock function with given fields: msg, keysAndValues +func (_m *Logger) Panicw(msg string, keysAndValues ...interface{}) { + var _ca []interface{} + _ca = append(_ca, msg) + _ca = append(_ca, keysAndValues...) + _m.Called(_ca...) +} + +// Recover provides a mock function with given fields: panicErr +func (_m *Logger) Recover(panicErr interface{}) { + _m.Called(panicErr) +} + +// SetLogLevel provides a mock function with given fields: _a0 +func (_m *Logger) SetLogLevel(_a0 zapcore.Level) { + _m.Called(_a0) +} + +// Sync provides a mock function with given fields: +func (_m *Logger) Sync() 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 +} + +// Trace provides a mock function with given fields: args +func (_m *Logger) Trace(args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// Tracef provides a mock function with given fields: format, values +func (_m *Logger) Tracef(format string, values ...interface{}) { + var _ca []interface{} + _ca = append(_ca, format) + _ca = append(_ca, values...) + _m.Called(_ca...) +} + +// Tracew provides a mock function with given fields: msg, keysAndValues +func (_m *Logger) Tracew(msg string, keysAndValues ...interface{}) { + var _ca []interface{} + _ca = append(_ca, msg) + _ca = append(_ca, keysAndValues...) + _m.Called(_ca...) +} + +// Warn provides a mock function with given fields: args +func (_m *Logger) Warn(args ...interface{}) { + var _ca []interface{} + _ca = append(_ca, args...) + _m.Called(_ca...) +} + +// Warnf provides a mock function with given fields: format, values +func (_m *Logger) Warnf(format string, values ...interface{}) { + var _ca []interface{} + _ca = append(_ca, format) + _ca = append(_ca, values...) + _m.Called(_ca...) +} + +// Warnw provides a mock function with given fields: msg, keysAndValues +func (_m *Logger) Warnw(msg string, keysAndValues ...interface{}) { + var _ca []interface{} + _ca = append(_ca, msg) + _ca = append(_ca, keysAndValues...) + _m.Called(_ca...) +} + +// With provides a mock function with given fields: args +func (_m *Logger) With(args ...interface{}) logger.Logger { + var _ca []interface{} + _ca = append(_ca, args...) + ret := _m.Called(_ca...) + + var r0 logger.Logger + if rf, ok := ret.Get(0).(func(...interface{}) logger.Logger); ok { + r0 = rf(args...) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(logger.Logger) + } + } + + return r0 +} + +type mockConstructorTestingTNewLogger interface { + mock.TestingT + Cleanup(func()) +} + +// NewLogger creates a new instance of Logger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewLogger(t mockConstructorTestingTNewLogger) *Logger { + mock := &Logger{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/scripts/ccip/manual-execution/helpers/contractmodels.go b/core/scripts/ccip/manual-execution/helpers/contractmodels.go index 4d7419e224..796173c594 100644 --- a/core/scripts/ccip/manual-execution/helpers/contractmodels.go +++ b/core/scripts/ccip/manual-execution/helpers/contractmodels.go @@ -18,10 +18,14 @@ type ICommitStoreCommitReport struct { MerkleRoot [32]byte } +type InternalGasPriceUpdate struct { + DestChainSelector uint64 + UsdPerUnitGas *big.Int +} + type InternalPriceUpdates struct { TokenPriceUpdates []InternalTokenPriceUpdate - DestChainId uint64 - UsdPerUnitGas *big.Int + GasPriceUpdates []InternalGasPriceUpdate } type InternalTokenPriceUpdate struct { diff --git a/core/scripts/common/helpers.go b/core/scripts/common/helpers.go index a58521ad2e..1cef61a3c6 100644 --- a/core/scripts/common/helpers.go +++ b/core/scripts/common/helpers.go @@ -216,6 +216,11 @@ func explorerLinkPrefix(chainID int64) (prefix string) { case 1666700000, 1666700001, 1666700002, 1666700003: // Harmony testnet prefix = "https://explorer.testnet.harmony.one" + case 84531: + prefix = "https://goerli.basescan.org" + case 8453: + prefix = "https://basescan.org" + default: // Unknown chain, return prefix as-is prefix = "" } @@ -412,7 +417,7 @@ func BinarySearch(top, bottom *big.Int, test func(amount *big.Int) bool) *big.In return bottom } -// Get RLP encoded headers of a list of block numbers +// GetRlpHeaders gets 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, getParentBlocks bool) (headers [][]byte, hashes []string, err error) { diff --git a/core/scripts/functions/templates/oracle.toml b/core/scripts/functions/templates/oracle.toml index 58f20afdd9..4739252d68 100644 --- a/core/scripts/functions/templates/oracle.toml +++ b/core/scripts/functions/templates/oracle.toml @@ -23,19 +23,19 @@ contractUpdateCheckFrequencySec = 300 contractVersion = 1 donID = "{{don_id}}" enableRequestSignatureCheck = false -listenerEventHandlerTimeoutSec = 180 +listenerEventHandlerTimeoutSec = 210 listenerEventsCheckFrequencyMillis = 500 maxRequestSizeBytes = 30_720 minIncomingConfirmations = 3 -pruneBatchSize = 5 -pruneCheckFrequencySec = 30 -pruneMaxStoredRequests = 20 -requestTimeoutBatchLookupSize = 20 +pruneBatchSize = 500 +pruneCheckFrequencySec = 600 +pruneMaxStoredRequests = 20_000 +requestTimeoutBatchLookupSize = 200 requestTimeoutCheckFrequencySec = 10 requestTimeoutSec = 300 maxRequestSizesList = [30_720, 51_200, 102_400, 204_800, 512_000, 1_048_576, 2_097_152, 3_145_728, 5_242_880, 10_485_760] maxSecretsSizesList = [10_240, 20_480, 51_200, 102_400, 307_200, 512_000, 1_048_576, 2_097_152] -minimumSubscriptionBalance = "0.1 link" +minimumSubscriptionBalance = "2 link" [pluginConfig.OnchainAllowlist] @@ -50,24 +50,25 @@ minimumSubscriptionBalance = "0.1 link" contractAddress = "{{router_contract_address}}" updateFrequencySec = 30 updateTimeoutSec = 10 - updateRangeSize = 100 + updateRangeSize = 2000 [pluginConfig.RateLimiter] - globalBurst = 5 - globalRPS = 10 - perSenderBurst = 1 - perSenderRPS = 0.2 + globalBurst = 30 + globalRPS = 20 + perSenderBurst = 5 + perSenderRPS = 1 [pluginConfig.S4Constraints] maxPayloadSizeBytes = 20_000 maxSlotsPerUser = 5 + maxExpirationLengthSec = 259_200 [pluginConfig.decryptionQueueConfig] completedCacheTimeoutSec = 300 - decryptRequestTimeoutSec = 100 - maxCiphertextBytes = 10_000 + decryptRequestTimeoutSec = 180 + maxCiphertextBytes = 20_000 maxCiphertextIdLength = 100 - maxQueueLength = 100 + maxQueueLength = 5_000 [pluginConfig.gatewayConnectorConfig] AuthMinChallengeLen = 20 diff --git a/core/scripts/gateway/client/send_request.go b/core/scripts/gateway/client/send_request.go index ad3ea1cc27..94ff6fb17d 100644 --- a/core/scripts/gateway/client/send_request.go +++ b/core/scripts/gateway/client/send_request.go @@ -8,9 +8,11 @@ import ( "fmt" "io" "net/http" + "os" "time" "github.com/ethereum/go-ethereum/crypto" + "github.com/joho/godotenv" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/api" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/functions" @@ -27,8 +29,19 @@ func main() { s4SetVersion := flag.Uint64("s4_set_version", 0, "S4 set version") s4SetExpirationPeriod := flag.Int64("s4_set_expiration_period", 60*60*1000, "S4 how long until the entry expires from now (in milliseconds)") s4SetPayload := flag.String("s4_set_payload", "", "S4 set payload") + repeat := flag.Bool("repeat", false, "Repeat sending the request every 10 seconds") flag.Parse() + if privateKey == nil || *privateKey == "" { + if err := godotenv.Load(); err != nil { + panic(err) + } + + privateKeyEnvVar := os.Getenv("PRIVATE_KEY") + privateKey = &privateKeyEnvVar + fmt.Println("Loaded private key from .env") + } + // validate key and extract address key, err := crypto.HexToECDSA(*privateKey) if err != nil { @@ -77,8 +90,7 @@ func main() { }, } - err = msg.Sign(key) - if err != nil { + if err = msg.Sign(key); err != nil { fmt.Println("error signing message", err) return } @@ -88,26 +100,44 @@ func main() { fmt.Println("error JSON-RPC encoding", err) return } - req, err := http.NewRequestWithContext(context.Background(), "POST", *gatewayURL, bytes.NewBuffer(rawMsg)) - if err != nil { - fmt.Println("error creating an HTTP request", err) + + createRequest := func() (req *http.Request, err error) { + req, err = http.NewRequestWithContext(context.Background(), "POST", *gatewayURL, bytes.NewBuffer(rawMsg)) + if err == nil { + req.Header.Set("Content-Type", "application/json") + } return } - req.Header.Set("Content-Type", "application/json") client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - fmt.Println("error sending a request", err) - return - } - defer resp.Body.Close() - body, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println("error sending a request", err) - return + sendRequest := func() { + req, err := createRequest() + if err != nil { + fmt.Println("error creating a request", err) + return + } + + resp, err := client.Do(req) + if err != nil { + fmt.Println("error sending a request", err) + return + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println("error sending a request", err) + return + } + + fmt.Println(string(body)) } - fmt.Println(string(body)) + sendRequest() + + for *repeat { + time.Sleep(10 * time.Second) + sendRequest() + } } diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 0f3b34d0cd..cb782f7192 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -1,6 +1,6 @@ module github.com/smartcontractkit/chainlink/core/scripts -go 1.20 +go 1.21 // Make sure we're working with the latest chainlink libs replace github.com/smartcontractkit/chainlink/v2 => ../../ @@ -16,16 +16,17 @@ require ( github.com/google/go-cmp v0.5.9 github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect github.com/google/uuid v1.3.1 + github.com/joho/godotenv v1.4.0 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.9 + github.com/pelletier/go-toml/v2 v2.1.0 github.com/pkg/errors v0.9.1 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/libocr v0.0.0-20230918212407-dbd4e505b3e6 - github.com/smartcontractkit/ocr2keepers v0.7.24 + github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6 + github.com/smartcontractkit/ocr2keepers v0.7.27 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb github.com/spf13/cobra v1.7.0 @@ -39,8 +40,6 @@ require ( gonum.org/v1/gonum v0.13.0 // indirect ) -require github.com/joho/godotenv v1.4.0 - require ( contrib.go.opencensus.io/exporter/stackdriver v0.13.5 // indirect cosmossdk.io/api v0.3.1 // indirect @@ -305,7 +304,7 @@ require ( github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 // indirect github.com/smartcontractkit/chain-selectors v1.0.2 // indirect github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230918212835-8a0b08df72a3 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230926113942-a871b2976dc1 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca // indirect github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1 // indirect github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index e51fc31b65..ff0502a90f 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -19,6 +19,7 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP 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.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk= +cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= 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= @@ -26,11 +27,14 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v1.22.0 h1:cB8R6FtUtT1TYGl5R3xuxnW6OUIc/DrT2aiR16TTG7Y= +cloud.google.com/go/compute v1.22.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= 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/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= 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= @@ -42,6 +46,7 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX 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.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= 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= @@ -55,9 +60,11 @@ cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3s 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/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= 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= +cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= 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= @@ -71,6 +78,7 @@ github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj4 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-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.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -93,32 +101,40 @@ github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtix github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= 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= 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.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/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= 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/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= 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/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= 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-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/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4= +github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= 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= @@ -134,8 +150,11 @@ github.com/avast/retry-go/v4 v4.5.0/go.mod h1:7hLEXp0oku2Nir2xBAsg0PTphp9z71bN5A 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.44.302 h1:ST3ko6GrJKn3Xi+nAvxjG3uk/V1pW8KC52WLeIxqqNk= +github.com/aws/aws-sdk-go v1.44.302/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= +github.com/aws/jsii-runtime-go v1.75.0/go.mod h1:TKCyrtM0pygEPo4rDZzbMSDNCDNTSYSN6/mGyHI6O3I= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= @@ -147,6 +166,7 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce 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/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= 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= @@ -158,6 +178,7 @@ github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/i github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.3 h1:xfbtw8lwpp0G6NwSHb+UE67ryTFHJAiNuipusjXSohQ= +github.com/btcsuite/btcd/btcutil v1.1.3/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= @@ -168,16 +189,20 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.2 h1:GDaNjuWSGu09guE9Oql0MSTNhNCLlWwO8y/xM5BzcbM= github.com/bytedance/sonic v1.9.2/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= 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/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -185,13 +210,16 @@ github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL 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/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/chaos-mesh/chaos-mesh/api/v1alpha1 v0.0.0-20220226050744-799408773657 h1:CyuI+igIjadM/GRnE2o0q+WCwipDh0n2cUYFPAvxziM= +github.com/chaos-mesh/chaos-mesh/api/v1alpha1 v0.0.0-20220226050744-799408773657/go.mod h1:JRiumF+RFsH1mrrP8FUsi9tExPylKkO/oSRWeQEUdLE= 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= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 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/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 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= @@ -200,10 +228,13 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX 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/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 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/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= +github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= 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= @@ -217,6 +248,7 @@ github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5w github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= 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/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= 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.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= @@ -224,6 +256,7 @@ github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3Hf 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.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU= +github.com/containerd/continuity v0.4.1/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= 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= @@ -244,6 +277,7 @@ github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXy github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= 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= @@ -255,15 +289,19 @@ github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980 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/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= 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/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= 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/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= 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= @@ -281,10 +319,12 @@ github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS3 github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= 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/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= 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= @@ -319,6 +359,7 @@ github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQx github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/emicklei/go-restful/v3 v3.10.2 h1:hIovbnmBTLjHXkqEBUz3HGpXZdM7ZrE9fJIZIqlJLqE= +github.com/emicklei/go-restful/v3 v3.10.2/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= @@ -327,16 +368,21 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= 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= github.com/ethereum/go-ethereum v1.12.0/go.mod h1:/oo2X/dZLJjf2mJ6YT9wcWxa4nNJDBKDBU6sFIpx1Gs= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f h1:Wl78ApPPB2Wvf/TIe2xdyJxTlb6obmF18d8QdkxNDu4= +github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= @@ -344,17 +390,22 @@ 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.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/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= 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/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 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= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fvbommel/sortorder v1.0.2 h1:mV4o8B2hKboCdkJm+a7uX/SIpZob4JzUpc5GGnM45eo= +github.com/fvbommel/sortorder v1.0.2/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/fxamacker/cbor/v2 v2.4.0 h1:ri0ArlOR+5XunOP8CRUowT0pSJOwhW098ZCUyskZD88= github.com/fxamacker/cbor/v2 v2.4.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= @@ -396,6 +447,7 @@ github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SU 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-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= @@ -420,10 +472,14 @@ github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AE 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/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= +github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= 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/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= +github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= 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/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -437,8 +493,10 @@ github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXS github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= +github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= 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-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= 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= @@ -459,6 +517,7 @@ 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= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= +github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/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= @@ -515,6 +574,7 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ 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/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= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -550,6 +610,7 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi 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/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= +github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= 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= @@ -565,22 +626,28 @@ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/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/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= 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= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= +github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= 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/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= 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= @@ -600,6 +667,7 @@ github.com/graph-gophers/dataloader v5.0.0+incompatible/go.mod h1:jk4jk0c5ZISbKa github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= 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.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= @@ -626,10 +694,13 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv 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-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= 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-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-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= 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= @@ -643,13 +714,16 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 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.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 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-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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= @@ -686,8 +760,10 @@ 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.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/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -804,10 +880,12 @@ 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/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= 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/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= @@ -816,6 +894,7 @@ github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -835,7 +914,9 @@ 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/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= @@ -1092,6 +1173,7 @@ github.com/libp2p/go-yamux v1.4.1/go.mod h1:fr7aVgmdNGJK+N1g+b6DW6VxzbRCjCOejR/h github.com/libp2p/go-yamux/v2 v2.0.0 h1:vSGhAy5u6iHBq11ZDcyHH4Blcf9xlBhT4WQDoOE90LU= 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/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= @@ -1103,7 +1185,9 @@ github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0V 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.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/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -1134,6 +1218,7 @@ github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWV 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 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= +github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 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= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -1151,6 +1236,7 @@ github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjK 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/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= 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= @@ -1166,6 +1252,7 @@ github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eI 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.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= @@ -1173,8 +1260,11 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh 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/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= 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.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= @@ -1183,9 +1273,11 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb 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/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.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= +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= @@ -1251,6 +1343,7 @@ github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXS github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +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/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= @@ -1259,6 +1352,7 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= +github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -1286,16 +1380,19 @@ 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/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/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/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.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= 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= @@ -1305,9 +1402,10 @@ 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.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= -github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/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= @@ -1355,12 +1453,15 @@ github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73 github.com/prometheus/prometheus v0.46.0/go.mod h1:10L5IJE5CEsjee1FnOcVswYXlPIscDWWt3IJ2UDYrz4= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= +github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= 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/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= 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-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/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= @@ -1378,12 +1479,15 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= 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.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= @@ -1420,20 +1524,23 @@ github.com/smartcontractkit/chain-selectors v1.0.2/go.mod h1:WBhLlODF5b95vvx2tdK github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47 h1:vdieOW3CZGdD2R5zvCSMS+0vksyExPN3/Fa1uVfld/A= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= github.com/smartcontractkit/chainlink-env v0.36.0 h1:CFOjs0c0y3lrHi/fl5qseCH9EQa5W/6CFyOvmhe2VnA= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230918212835-8a0b08df72a3 h1:FonaZ1kgRK0yY7D0jF5pL3K+0DYUnKcnStOOcIN+Hhg= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230918212835-8a0b08df72a3/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-env v0.36.0/go.mod h1:NbRExHmJGnKSYXmvNuJx5VErSx26GtE1AEN/CRzYOg8= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230926113942-a871b2976dc1 h1:Db333w+fSm2e18LMikcIQHIZqgxZruW9uCUGJLUC9mI= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230926113942-a871b2976dc1/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918/go.mod h1:/yp/sqD8Iz5GU5fcercjrw0ivJF7HDcupYg+Gjr7EPg= github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230825001100-85c8b45d8005 h1:c1RWSbfF+rvkxAcwrXEJVGiIr3cpdZb+zok8o+qEWwQ= +github.com/smartcontractkit/chainlink-testing-framework v1.16.1-0.20230825001100-85c8b45d8005/go.mod h1:t6FJX3akEfAO31p96ru0ilNPfE9P2UshUlXTIkI58LM= github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230828183543-6d0939746966 h1:18MPun8xOGNhP3dGPvr9nYENEKhuhHNPMIQzOsiN6l4= +github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230828183543-6d0939746966/go.mod h1:RcA3U87XQ2VqXkEG4PuHz2uZiFyXBtUHcFddeHJTWSk= 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-20230918212407-dbd4e505b3e6 h1:w+8TI2Vcm3vk8XQz40ddcwy9BNZgoakXIby35Y54iDU= -github.com/smartcontractkit/libocr v0.0.0-20230918212407-dbd4e505b3e6/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.24 h1:d1HcCpsBcBSC9MC9qdjzsm/NSAnnavcZAvAqPAAa75Q= -github.com/smartcontractkit/ocr2keepers v0.7.24/go.mod h1:4e1ZDRz7fpLgcRUjJpq+5mkoD0ga11BxrSp2JTWKADQ= +github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6 h1:eSo9r53fARv2MnIO5pqYvQOXMBsTlAwhHyQ6BAVp6bY= +github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.7.27 h1:kwqMrzmEdq6gH4yqNuLQCbdlED0KaIjwZzu3FF+Gves= +github.com/smartcontractkit/ocr2keepers v0.7.27/go.mod h1:1QGzJURnoWpysguPowOe2bshV0hNp1YX10HHlhDEsas= 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= @@ -1542,6 +1649,7 @@ github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95 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/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -1553,6 +1661,7 @@ github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQ 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/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= 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= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -1577,8 +1686,10 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1: github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 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/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= 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= @@ -1630,16 +1741,19 @@ 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.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.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.10/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= @@ -1816,6 +1930,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/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.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= @@ -2028,7 +2143,9 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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-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.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -2052,6 +2169,7 @@ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ 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.132.0 h1:8t2/+qZ26kAOGSmOiHwVycqVaDg7q3JDILrNi/Z6rvc= +google.golang.org/api v0.132.0/go.mod h1:AeTBC6GpJnJSRJjktDcPX0QwtS8pGYZOV6MSuSCusw0= 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= @@ -2172,6 +2290,7 @@ 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= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= @@ -2187,6 +2306,7 @@ gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFab gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= +gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= 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= @@ -2204,6 +2324,7 @@ 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.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= 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= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2213,27 +2334,46 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 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.4 h1:3YO8J4RtmG7elEgaWMb4HgmpS2CfY1QlaOz9nwB+ZSs= +k8s.io/api v0.25.4/go.mod h1:IG2+RzyPQLllQxnhzD8KQNEu4c4YvyDTpSMztf4A0OQ= 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.27.3 h1:Ubye8oBufD04l9QnNtW05idcOe9Z3GQN8+7PqmuVcUM= +k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= 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.4 h1:3RNRDffAkNU56M/a7gUfXaEzdhZlYhoW8dgViGy5fn8= k8s.io/client-go v0.25.4/go.mod h1:8trHCAC83XKY0wsBIpbirZU4NTUpbuhc2JnI7OruGZw= k8s.io/component-base v0.26.2 h1:IfWgCGUDzrD6wLLgXEstJKYZKAFS2kO+rBRi0p3LqcI= +k8s.io/component-base v0.26.2/go.mod h1:DxbuIe9M3IZPRxPIzhch2m1eT7uFrSBJUBuVCQEBivs= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515 h1:OmK1d0WrkD3IPfkskvroRykOulHVHf0s0ZIFRjyt+UI= +k8s.io/kube-openapi v0.0.0-20230525220651-2546d827e515/go.mod h1:kzo02I3kQ4BTtEfVLaPbjvCkX97YqGve33wzlb3fofQ= 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-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= +k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= +lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= modernc.org/ccgo/v3 v3.16.14 h1:af6KNtFgsVmnDYrWk3PQCS9XT6BXe7o3ZFJKkIKvXNQ= +modernc.org/ccgo/v3 v3.16.14/go.mod h1:mPDSujUIaTNWQSG4eqKw+atqLOEbma6Ncsa94WbC9zo= modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM= +modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o= +modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA= +modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= 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= @@ -2243,9 +2383,14 @@ rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= 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-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= +sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= +sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/core/scripts/vrfv2/testnet/main.go b/core/scripts/vrfv2/testnet/main.go index d30c0e7fca..d418eb6d15 100644 --- a/core/scripts/vrfv2/testnet/main.go +++ b/core/scripts/vrfv2/testnet/main.go @@ -418,12 +418,19 @@ func main() { } if *startBlock == -1 { - tx, err2 := bhs.StoreEarliest(e.Owner) - helpers.PanicErr(err2) - receipt := helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, "Store Earliest") - // storeEarliest will store receipt block number minus 256 which is the earliest block - // the blockhash() instruction will work on. - *startBlock = receipt.BlockNumber.Int64() - 256 + closestBlock, err2 := scripts.ClosestBlock(e, common.HexToAddress(*batchAddr), uint64(*endBlock), uint64(*batchSize)) + // found a block with blockhash stored that's more recent that end block + if err2 == nil { + *startBlock = int64(closestBlock) + } else { + fmt.Println("encountered error while looking for closest block:", err2) + tx, err2 := bhs.StoreEarliest(e.Owner) + helpers.PanicErr(err2) + receipt := helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, "Store Earliest") + // storeEarliest will store receipt block number minus 256 which is the earliest block + // the blockhash() instruction will work on. + *startBlock = receipt.BlockNumber.Int64() - 256 + } } // Check if the provided start block is in the BHS. If it's not, print out an appropriate @@ -476,6 +483,7 @@ func main() { helpers.PanicErr(err) fmt.Println("received receipt, continuing") + fmt.Println("there are", len(blockRange)-j, "blocks left to store") } fmt.Println("done") case "latest-head": @@ -1330,6 +1338,14 @@ func main() { blockNumber := cmd.Int("block-number", -1, "block number") helpers.ParseArgs(cmd, os.Args[2:]) _ = helpers.CalculateLatestBlockHeader(e, *blockNumber) + case "closest-block": + cmd := flag.NewFlagSet("closest-block", flag.ExitOnError) + blockNumber := cmd.Uint64("block-number", 0, "block number") + batchBHSAddress := cmd.String("batch-bhs-address", "", "address of the batch blockhash store") + batchSize := cmd.Uint64("batch-size", 100, "batch size") + helpers.ParseArgs(cmd, os.Args[2:], "block-number", "batch-bhs-address") + _, err := scripts.ClosestBlock(e, common.HexToAddress(*batchBHSAddress), *blockNumber, *batchSize) + helpers.PanicErr(err) case "wrapper-universe-deploy": scripts.DeployWrapperUniverse(e) default: diff --git a/core/scripts/vrfv2/testnet/scripts/util.go b/core/scripts/vrfv2/testnet/scripts/util.go index 3b429837c9..a55a78adb5 100644 --- a/core/scripts/vrfv2/testnet/scripts/util.go +++ b/core/scripts/vrfv2/testnet/scripts/util.go @@ -3,11 +3,14 @@ package scripts import ( "context" "encoding/hex" + "errors" "fmt" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_load_test_with_metrics" "math/big" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_load_test_with_metrics" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" helpers "github.com/smartcontractkit/chainlink/core/scripts/common" @@ -212,3 +215,39 @@ func EoaLoadTestConsumerWithMetricsDeploy(e helpers.Environment, consumerCoordin helpers.PanicErr(err) return helpers.ConfirmContractDeployed(context.Background(), e.Ec, tx, e.ChainID) } + +func ClosestBlock(e helpers.Environment, batchBHSAddress common.Address, blockMissingBlockhash uint64, batchSize uint64) (uint64, error) { + batchBHS, err := batch_blockhash_store.NewBatchBlockhashStore(batchBHSAddress, e.Ec) + if err != nil { + return 0, err + } + startBlock := blockMissingBlockhash + 1 + endBlock := startBlock + batchSize + for { + latestBlock, err := e.Ec.HeaderByNumber(context.Background(), nil) + if err != nil { + return 0, err + } + if latestBlock.Number.Uint64() < endBlock { + return 0, errors.New("closest block with blockhash not found") + } + var blockRange []*big.Int + for i := startBlock; i <= endBlock; i++ { + blockRange = append(blockRange, big.NewInt(int64(i))) + } + fmt.Println("Searching range", startBlock, "-", endBlock, "inclusive") + hashes, err := batchBHS.GetBlockhashes(nil, blockRange) + if err != nil { + return 0, err + } + for i, hash := range hashes { + if hash != (common.Hash{}) { + fmt.Println("found closest block:", startBlock+uint64(i), "hash:", hexutil.Encode(hash[:])) + fmt.Println("distance from missing block:", startBlock+uint64(i)-blockMissingBlockhash) + return startBlock + uint64(i), nil + } + } + startBlock = endBlock + 1 + endBlock = startBlock + batchSize + } +} diff --git a/core/scripts/vrfv2plus/testnet/main.go b/core/scripts/vrfv2plus/testnet/main.go index 95c98ad1bb..7bc6410866 100644 --- a/core/scripts/vrfv2plus/testnet/main.go +++ b/core/scripts/vrfv2plus/testnet/main.go @@ -6,12 +6,15 @@ import ( "encoding/hex" "flag" "fmt" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" "log" "math/big" "os" "strings" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus_interface" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -29,7 +32,6 @@ import ( "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_v2plus_single_consumer" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_sub_owner" @@ -46,12 +48,17 @@ import ( var ( batchCoordinatorV2PlusABI = evmtypes.MustGetABI(batch_vrf_coordinator_v2plus.BatchVRFCoordinatorV2PlusABI) + coordinatorV2PlusABI = evmtypes.MustGetABI(vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalABI) ) func main() { e := helpers.SetupEnv(false) switch os.Args[1] { + case "smoke": + smokeTestVRF(e) + case "smoke-bhs": + smokeTestBHS(e) case "manual-fulfill": cmd := flag.NewFlagSet("manual-fulfill", flag.ExitOnError) // In order to get the tx data for a fulfillment transaction, you can grep the @@ -89,8 +96,8 @@ func main() { helpers.ConfirmTXMined(context.Background(), e.Ec, signedTx, e.ChainID, fmt.Sprintf("manual fulfillment %d", i+1)) } case "topics": - randomWordsRequested := vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested{}.Topic() - randomWordsFulfilled := vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled{}.Topic() + randomWordsRequested := vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested{}.Topic() + randomWordsFulfilled := vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled{}.Topic() fmt.Println("RandomWordsRequested:", randomWordsRequested.String(), "RandomWordsFulfilled:", randomWordsFulfilled.String()) case "batch-coordinatorv2plus-deploy": @@ -231,7 +238,7 @@ func main() { "subid", "cbgaslimit", "numwords", "sender", ) - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddr), e.Ec) + coordinator, err := vrf_coordinator_v2plus_interface.NewIVRFCoordinatorV2PlusInternal(common.HexToAddress(*coordinatorAddr), e.Ec) helpers.PanicErr(err) db := sqlx.MustOpen("postgres", *dbURL) @@ -473,7 +480,7 @@ func main() { coordinatorAddress := cmd.String("coordinator-address", "", "coordinator address") helpers.ParseArgs(cmd, os.Args[2:], "coordinator-address") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) printCoordinatorConfig(coordinator) @@ -489,7 +496,7 @@ func main() { flatFeeEthPPM := cmd.Int64("flat-fee-eth-ppm", 500, "fulfillment flat fee ETH ppm") helpers.ParseArgs(cmd, os.Args[2:], "coordinator-address", "fallback-wei-per-unit-link") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*setConfigAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*setConfigAddress), e.Ec) helpers.PanicErr(err) setCoordinatorConfig( @@ -500,9 +507,9 @@ func main() { uint32(*stalenessSeconds), uint32(*gasAfterPayment), decimal.RequireFromString(*fallbackWeiPerUnitLink).BigInt(), - vrf_coordinator_v2plus.VRFCoordinatorV2PlusFeeConfig{ - FulfillmentFlatFeeLinkPPM: uint32(*flatFeeLinkPPM), - FulfillmentFlatFeeEthPPM: uint32(*flatFeeEthPPM), + vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig{ + FulfillmentFlatFeeLinkPPM: uint32(*flatFeeLinkPPM), + FulfillmentFlatFeeNativePPM: uint32(*flatFeeEthPPM), }, ) case "coordinator-register-key": @@ -511,7 +518,7 @@ func main() { registerKeyUncompressedPubKey := coordinatorRegisterKey.String("pubkey", "", "uncompressed pubkey") registerKeyOracleAddress := coordinatorRegisterKey.String("oracle-address", "", "oracle address") helpers.ParseArgs(coordinatorRegisterKey, os.Args[2:], "address", "pubkey", "oracle-address") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*registerKeyAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*registerKeyAddress), e.Ec) helpers.PanicErr(err) // Put key in ECDSA format @@ -525,7 +532,7 @@ func main() { deregisterKeyAddress := coordinatorDeregisterKey.String("address", "", "coordinator address") deregisterKeyUncompressedPubKey := coordinatorDeregisterKey.String("pubkey", "", "uncompressed pubkey") helpers.ParseArgs(coordinatorDeregisterKey, os.Args[2:], "address", "pubkey") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*deregisterKeyAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*deregisterKeyAddress), e.Ec) helpers.PanicErr(err) // Put key in ECDSA format @@ -544,7 +551,7 @@ func main() { address := coordinatorSub.String("address", "", "coordinator address") subID := coordinatorSub.String("sub-id", "", "sub-id") helpers.ParseArgs(coordinatorSub, os.Args[2:], "address", "sub-id") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*address), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*address), e.Ec) helpers.PanicErr(err) fmt.Println("sub-id", *subID, "address", *address, coordinator.Address()) parsedSubID := parseSubID(*subID) @@ -688,7 +695,7 @@ func main() { createSubCmd := flag.NewFlagSet("eoa-create-sub", flag.ExitOnError) coordinatorAddress := createSubCmd.String("coordinator-address", "", "coordinator address") helpers.ParseArgs(createSubCmd, os.Args[2:], "coordinator-address") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) eoaCreateSub(e, *coordinator) case "eoa-add-sub-consumer": @@ -697,7 +704,7 @@ func main() { subID := addSubConsCmd.String("sub-id", "", "sub-id") consumerAddress := addSubConsCmd.String("consumer-address", "", "consumer address") helpers.ParseArgs(addSubConsCmd, os.Args[2:], "coordinator-address", "sub-id", "consumer-address") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) parsedSubID := parseSubID(*subID) eoaAddConsumerToSub(e, *coordinator, parsedSubID, *consumerAddress) @@ -713,14 +720,14 @@ func main() { if !s { panic(fmt.Sprintf("failed to parse top up amount '%s'", *amountStr)) } - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) fmt.Println(amount, consumerLinkAddress) txcreate, err := coordinator.CreateSubscription(e.Owner) helpers.PanicErr(err) fmt.Println("Create sub", "TX", helpers.ExplorerLink(e.ChainID, txcreate.Hash())) helpers.ConfirmTXMined(context.Background(), e.Ec, txcreate, e.ChainID) - sub := make(chan *vrf_coordinator_v2plus.VRFCoordinatorV2PlusSubscriptionCreated) + sub := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25SubscriptionCreated) subscription, err := coordinator.WatchSubscriptionCreated(nil, sub, nil) helpers.PanicErr(err) defer subscription.Unsubscribe() @@ -736,7 +743,7 @@ func main() { tx, err := linkToken.TransferAndCall(e.Owner, coordinator.Address(), amount, b) helpers.PanicErr(err) helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, fmt.Sprintf("Sub id: %d", created.SubId)) - subFunded := make(chan *vrf_coordinator_v2plus.VRFCoordinatorV2PlusSubscriptionFunded) + subFunded := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25SubscriptionFunded) fundSub, err := coordinator.WatchSubscriptionFunded(nil, subFunded, []*big.Int{created.SubId}) helpers.PanicErr(err) defer fundSub.Unsubscribe() @@ -881,7 +888,7 @@ func main() { subID := trans.String("sub-id", "", "sub-id") to := trans.String("to", "", "to") helpers.ParseArgs(trans, os.Args[2:], "coordinator-address", "sub-id", "to") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) tx, err := coordinator.RequestSubscriptionOwnerTransfer(e.Owner, parseSubID(*subID), common.HexToAddress(*to)) helpers.PanicErr(err) @@ -891,7 +898,7 @@ func main() { coordinatorAddress := accept.String("coordinator-address", "", "coordinator address") subID := accept.String("sub-id", "", "sub-id") helpers.ParseArgs(accept, os.Args[2:], "coordinator-address", "sub-id") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) tx, err := coordinator.AcceptSubscriptionOwnerTransfer(e.Owner, parseSubID(*subID)) helpers.PanicErr(err) @@ -901,7 +908,7 @@ func main() { coordinatorAddress := cancel.String("coordinator-address", "", "coordinator address") subID := cancel.String("sub-id", "", "sub-id") helpers.ParseArgs(cancel, os.Args[2:], "coordinator-address", "sub-id") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) tx, err := coordinator.CancelSubscription(e.Owner, parseSubID(*subID), e.Owner.From) helpers.PanicErr(err) @@ -916,10 +923,10 @@ func main() { if !s { panic(fmt.Sprintf("failed to parse top up amount '%s'", *amountStr)) } - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) e.Owner.Value = amount - tx, err := coordinator.FundSubscriptionWithEth(e.Owner, parseSubID(*subID)) + tx, err := coordinator.FundSubscriptionWithNative(e.Owner, parseSubID(*subID)) helpers.PanicErr(err) helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID) case "eoa-fund-sub": @@ -933,7 +940,7 @@ func main() { if !s { panic(fmt.Sprintf("failed to parse top up amount '%s'", *amountStr)) } - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) eoaFundSubscription(e, *coordinator, *consumerLinkAddress, amount, parseSubID(*subID)) @@ -955,7 +962,7 @@ func main() { coordinatorAddress := cancel.String("coordinator-address", "", "coordinator address") subID := cancel.String("sub-id", "", "sub-id") helpers.ParseArgs(cancel, os.Args[2:], "coordinator-address", "sub-id") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) tx, err := coordinator.OwnerCancelSubscription(e.Owner, parseSubID(*subID)) helpers.PanicErr(err) @@ -965,7 +972,7 @@ func main() { coordinatorAddress := consumerBalanceCmd.String("coordinator-address", "", "coordinator address") subID := consumerBalanceCmd.String("sub-id", "", "subscription id") helpers.ParseArgs(consumerBalanceCmd, os.Args[2:], "coordinator-address", "sub-id") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) resp, err := coordinator.GetSubscription(nil, parseSubID(*subID)) helpers.PanicErr(err) @@ -979,7 +986,7 @@ func main() { coordinatorAddress := common.HexToAddress(*coordinator) oracleAddress := common.HexToAddress(*oracle) - abi, err := vrf_coordinator_v2plus.VRFCoordinatorV2PlusMetaData.GetAbi() + abi, err := vrf_coordinator_v2_5.VRFCoordinatorV25MetaData.GetAbi() helpers.PanicErr(err) isWithdrawable := func(amount *big.Int) bool { @@ -1009,7 +1016,7 @@ func main() { newOwner := cmd.String("new-owner", "", "new owner address") helpers.ParseArgs(cmd, os.Args[2:], "coordinator-address", "new-owner") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) tx, err := coordinator.TransferOwnership(e.Owner, common.HexToAddress(*newOwner)) @@ -1024,7 +1031,7 @@ func main() { skipDeregister := coordinatorReregisterKey.Bool("skip-deregister", false, "if true, key will not be deregistered") helpers.ParseArgs(coordinatorReregisterKey, os.Args[2:], "coordinator-address", "pubkey", "new-oracle-address") - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) // Put key in ECDSA format diff --git a/core/scripts/vrfv2plus/testnet/super_scripts.go b/core/scripts/vrfv2plus/testnet/super_scripts.go index a617733cb1..f9efde8f14 100644 --- a/core/scripts/vrfv2plus/testnet/super_scripts.go +++ b/core/scripts/vrfv2plus/testnet/super_scripts.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "context" "encoding/hex" "flag" @@ -9,16 +10,24 @@ import ( "os" "strings" + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" "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" + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_blockhash_store" + "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/vrf_coordinator_v2plus" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_sub_owner" + "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/proof" ) const formattedVRFJob = ` @@ -60,6 +69,423 @@ decode_log->generate_proof->estimate_gas->simulate_fulfillment """ ` +func smokeTestVRF(e helpers.Environment) { + smokeCmd := flag.NewFlagSet("smoke", flag.ExitOnError) + + // required flags + linkAddress := smokeCmd.String("link-address", "", "address of link token") + linkEthAddress := smokeCmd.String("link-eth-feed", "", "address of link eth feed") + bhsAddressStr := smokeCmd.String("bhs-address", "", "address of blockhash store") + batchBHSAddressStr := smokeCmd.String("batch-bhs-address", "", "address of batch blockhash store") + coordinatorAddressStr := smokeCmd.String("coordinator-address", "", "address of the vrf coordinator v2 contract") + batchCoordinatorAddressStr := smokeCmd.String("batch-coordinator-address", "", "address of the batch vrf coordinator v2 contract") + subscriptionBalanceString := smokeCmd.String("subscription-balance", "1e19", "amount to fund subscription") + skipConfig := smokeCmd.Bool("skip-config", false, "skip setting coordinator config") + + // optional flags + fallbackWeiPerUnitLinkString := smokeCmd.String("fallback-wei-per-unit-link", "6e16", "fallback wei/link ratio") + minConfs := smokeCmd.Int("min-confs", 3, "min confs") + maxGasLimit := smokeCmd.Int64("max-gas-limit", 2.5e6, "max gas limit") + stalenessSeconds := smokeCmd.Int64("staleness-seconds", 86400, "staleness in seconds") + gasAfterPayment := smokeCmd.Int64("gas-after-payment", 33285, "gas after payment calculation") + flatFeeLinkPPM := smokeCmd.Int64("flat-fee-link-ppm", 500, "fulfillment flat fee LINK ppm") + flatFeeEthPPM := smokeCmd.Int64("flat-fee-eth-ppm", 500, "fulfillment flat fee ETH ppm") + + helpers.ParseArgs( + smokeCmd, os.Args[2:], + ) + + fallbackWeiPerUnitLink := decimal.RequireFromString(*fallbackWeiPerUnitLinkString).BigInt() + subscriptionBalance := decimal.RequireFromString(*subscriptionBalanceString).BigInt() + + // generate VRF key + key, err := vrfkey.NewV2() + helpers.PanicErr(err) + fmt.Println("vrf private key:", hexutil.Encode(key.Raw())) + fmt.Println("vrf public key:", key.PublicKey.String()) + fmt.Println("vrf key hash:", key.PublicKey.MustHash()) + + 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 + } + + var bhsContractAddress common.Address + if len(*bhsAddressStr) == 0 { + fmt.Println("\nDeploying BHS...") + bhsContractAddress = deployBHS(e) + } else { + bhsContractAddress = common.HexToAddress(*bhsAddressStr) + } + + var batchBHSAddress common.Address + if len(*batchBHSAddressStr) == 0 { + fmt.Println("\nDeploying Batch BHS...") + batchBHSAddress = deployBatchBHS(e, bhsContractAddress) + } else { + batchBHSAddress = common.HexToAddress(*batchBHSAddressStr) + } + + var coordinatorAddress common.Address + if len(*coordinatorAddressStr) == 0 { + fmt.Println("\nDeploying Coordinator...") + coordinatorAddress = deployCoordinator(e, *linkAddress, bhsContractAddress.String(), *linkEthAddress) + } else { + coordinatorAddress = common.HexToAddress(*coordinatorAddressStr) + } + + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(coordinatorAddress, e.Ec) + helpers.PanicErr(err) + + var batchCoordinatorAddress common.Address + if len(*batchCoordinatorAddressStr) == 0 { + fmt.Println("\nDeploying Batch Coordinator...") + batchCoordinatorAddress = deployBatchCoordinatorV2(e, coordinatorAddress) + } else { + batchCoordinatorAddress = common.HexToAddress(*batchCoordinatorAddressStr) + } + + if !*skipConfig { + fmt.Println("\nSetting Coordinator Config...") + setCoordinatorConfig( + e, + *coordinator, + uint16(*minConfs), + uint32(*maxGasLimit), + uint32(*stalenessSeconds), + uint32(*gasAfterPayment), + fallbackWeiPerUnitLink, + vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig{ + FulfillmentFlatFeeLinkPPM: uint32(*flatFeeLinkPPM), + FulfillmentFlatFeeNativePPM: uint32(*flatFeeEthPPM), + }, + ) + } + + fmt.Println("\nConfig set, getting current config from deployed contract...") + printCoordinatorConfig(coordinator) + + // Generate compressed public key and key hash + uncompressed, err := key.PublicKey.StringUncompressed() + helpers.PanicErr(err) + if strings.HasPrefix(uncompressed, "0x") { + uncompressed = strings.Replace(uncompressed, "0x", "04", 1) + } + pubBytes, err := hex.DecodeString(uncompressed) + 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) + fmt.Println("vrf key hash from unmarshal:", hexutil.Encode(keyHash[:])) + fmt.Println("vrf key hash from key:", key.PublicKey.MustHash()) + if kh := key.PublicKey.MustHash(); !bytes.Equal(keyHash[:], kh[:]) { + panic(fmt.Sprintf("unexpected key hash %s, expected %s", hexutil.Encode(keyHash[:]), key.PublicKey.MustHash().String())) + } + fmt.Println("compressed public key from unmarshal:", compressedPkHex) + fmt.Println("compressed public key from key:", key.PublicKey.String()) + if compressedPkHex != key.PublicKey.String() { + panic(fmt.Sprintf("unexpected compressed public key %s, expected %s", compressedPkHex, key.PublicKey.String())) + } + + kh1, err := coordinator.HashOfKey(nil, [2]*big.Int{pk.X, pk.Y}) + helpers.PanicErr(err) + fmt.Println("key hash from coordinator:", hexutil.Encode(kh1[:])) + if !bytes.Equal(kh1[:], keyHash[:]) { + panic(fmt.Sprintf("unexpected key hash %s, expected %s", hexutil.Encode(kh1[:]), hexutil.Encode(keyHash[:]))) + } + + fmt.Println("\nRegistering proving key...") + point, err := key.PublicKey.Point() + helpers.PanicErr(err) + x, y := secp256k1.Coordinates(point) + fmt.Println("proving key points x:", x, ", y:", y) + fmt.Println("proving key points from unmarshal:", pk.X, pk.Y) + tx, err := coordinator.RegisterProvingKey(e.Owner, e.Owner.From, [2]*big.Int{x, y}) + helpers.PanicErr(err) + registerReceipt := helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, "register proving key on", coordinatorAddress.String()) + var provingKeyRegisteredLog *vrf_coordinator_v2_5.VRFCoordinatorV25ProvingKeyRegistered + for _, log := range registerReceipt.Logs { + if log.Address == coordinatorAddress { + var err error + provingKeyRegisteredLog, err = coordinator.ParseProvingKeyRegistered(*log) + if err != nil { + continue + } + } + } + if provingKeyRegisteredLog == nil { + panic("no proving key registered log found") + } + if !bytes.Equal(provingKeyRegisteredLog.KeyHash[:], keyHash[:]) { + panic(fmt.Sprintf("unexpected key hash registered %s, expected %s", hexutil.Encode(provingKeyRegisteredLog.KeyHash[:]), hexutil.Encode(keyHash[:]))) + } else { + fmt.Println("key hash registered:", hexutil.Encode(provingKeyRegisteredLog.KeyHash[:])) + } + + 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:", hexutil.Encode(provingKeyHashes[len(provingKeyHashes)-1][:])) + ourKeyHash := key.PublicKey.MustHash() + if !bytes.Equal(provingKeyHashes[len(provingKeyHashes)-1][:], ourKeyHash[:]) { + panic(fmt.Sprintf("unexpected key hash %s, expected %s", hexutil.Encode(provingKeyHashes[len(provingKeyHashes)-1][:]), hexutil.Encode(ourKeyHash[:]))) + } + + fmt.Println("\nDeploying consumer...") + consumerAddress := eoaDeployConsumer(e, coordinatorAddress.String(), *linkAddress) + + fmt.Println("\nAdding subscription...") + eoaCreateSub(e, *coordinator) + + subID := findSubscriptionID(e, coordinator) + helpers.PanicErr(err) + + 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) + + 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, + ) + + fmt.Println("making a request on consumer", consumerAddress) + consumer, err := vrf_v2plus_sub_owner.NewVRFV2PlusExternalSubOwnerExample(consumerAddress, e.Ec) + helpers.PanicErr(err) + tx, err = consumer.RequestRandomWords(e.Owner, subID, 100_000, 3, 3, provingKeyRegisteredLog.KeyHash, false) + receipt := helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, "request random words from", consumerAddress.String()) + fmt.Println("request blockhash:", receipt.BlockHash) + + // extract the RandomWordsRequested log from the receipt logs + var rwrLog *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested + for _, log := range receipt.Logs { + if log.Address == coordinatorAddress { + var err error + rwrLog, err = coordinator.ParseRandomWordsRequested(*log) + if err != nil { + continue + } + } + } + if rwrLog == nil { + panic("no RandomWordsRequested log found") + } + + fmt.Println("key hash:", hexutil.Encode(rwrLog.KeyHash[:])) + fmt.Println("request id:", rwrLog.RequestId) + fmt.Println("preseed:", rwrLog.PreSeed) + fmt.Println("num words:", rwrLog.NumWords) + fmt.Println("callback gas limit:", rwrLog.CallbackGasLimit) + fmt.Println("sender:", rwrLog.Sender) + fmt.Println("extra args:", hexutil.Encode(rwrLog.ExtraArgs)) + + // generate the VRF proof, follow the same process as the node + // we assume there is enough funds in the subscription to pay for the gas + preSeed, err := proof.BigToSeed(rwrLog.PreSeed) + helpers.PanicErr(err) + + preSeedData := proof.PreSeedDataV2Plus{ + PreSeed: preSeed, + BlockHash: rwrLog.Raw.BlockHash, + BlockNum: rwrLog.Raw.BlockNumber, + SubId: rwrLog.SubId, + CallbackGasLimit: rwrLog.CallbackGasLimit, + NumWords: rwrLog.NumWords, + Sender: rwrLog.Sender, + ExtraArgs: rwrLog.ExtraArgs, + } + finalSeed := proof.FinalSeedV2Plus(preSeedData) + pf, err := key.GenerateProof(finalSeed) + helpers.PanicErr(err) + onChainProof, rc, err := proof.GenerateProofResponseFromProofV2Plus(pf, preSeedData) + helpers.PanicErr(err) + b, err := coordinatorV2PlusABI.Pack("fulfillRandomWords", onChainProof, rc) + helpers.PanicErr(err) + fmt.Println("calldata for fulfillRandomWords:", hexutil.Encode(b)) + + // call fulfillRandomWords with onChainProof and rc appropriately + fmt.Println("proof c:", onChainProof.C) + fmt.Println("proof s:", onChainProof.S) + fmt.Println("proof gamma:", onChainProof.Gamma) + fmt.Println("proof seed:", onChainProof.Seed) + fmt.Println("proof pk:", onChainProof.Pk) + fmt.Println("proof c gamma witness:", onChainProof.CGammaWitness) + fmt.Println("proof u witness:", onChainProof.UWitness) + fmt.Println("proof s hash witness:", onChainProof.SHashWitness) + fmt.Println("proof z inv:", onChainProof.ZInv) + fmt.Println("request commitment sub id:", rc.SubId) + fmt.Println("request commitment callback gas limit:", rc.CallbackGasLimit) + fmt.Println("request commitment num words:", rc.NumWords) + fmt.Println("request commitment sender:", rc.Sender) + fmt.Println("request commitment extra args:", hexutil.Encode(rc.ExtraArgs)) + + receipt, txHash := sendTx(e, coordinatorAddress, b) + if receipt.Status != 1 { + fmt.Println("fulfillment tx failed, extracting revert reason") + tx, _, err := e.Ec.TransactionByHash(context.Background(), txHash) + helpers.PanicErr(err) + call := ethereum.CallMsg{ + From: e.Owner.From, + To: tx.To(), + Data: tx.Data(), + Gas: tx.Gas(), + GasPrice: tx.GasPrice(), + } + r, err := e.Ec.CallContract(context.Background(), call, receipt.BlockNumber) + fmt.Println("call contract", "r", r, "err", err) + rpcError, err := evmclient.ExtractRPCError(err) + fmt.Println("extracting rpc error", rpcError.String(), err) + os.Exit(1) + } + + fmt.Println("\nfulfillment successful") +} + +func smokeTestBHS(e helpers.Environment) { + smokeCmd := flag.NewFlagSet("smoke-bhs", flag.ExitOnError) + + // optional args + bhsAddress := smokeCmd.String("bhs-address", "", "address of blockhash store") + batchBHSAddress := smokeCmd.String("batch-bhs-address", "", "address of batch blockhash store") + + helpers.ParseArgs(smokeCmd, os.Args[2:]) + + var bhsContractAddress common.Address + if len(*bhsAddress) == 0 { + fmt.Println("\nDeploying BHS...") + bhsContractAddress = deployBHS(e) + } else { + bhsContractAddress = common.HexToAddress(*bhsAddress) + } + + var batchBHSContractAddress common.Address + if len(*batchBHSAddress) == 0 { + fmt.Println("\nDeploying Batch BHS...") + batchBHSContractAddress = deployBatchBHS(e, bhsContractAddress) + } else { + batchBHSContractAddress = common.HexToAddress(*batchBHSAddress) + } + + bhs, err := blockhash_store.NewBlockhashStore(bhsContractAddress, e.Ec) + helpers.PanicErr(err) + + batchBHS, err := batch_blockhash_store.NewBatchBlockhashStore(batchBHSContractAddress, e.Ec) + helpers.PanicErr(err) + batchBHS.Address() + + fmt.Println("\nexecuting storeEarliest") + tx, err := bhs.StoreEarliest(e.Owner) + helpers.PanicErr(err) + seReceipt := helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, "storeEarliest on", bhsContractAddress.String()) + var anchorBlockNumber *big.Int + if seReceipt.Status != 1 { + fmt.Println("storeEarliest failed") + os.Exit(1) + } else { + fmt.Println("storeEarliest succeeded, checking BH is there") + bh, err := bhs.GetBlockhash(nil, seReceipt.BlockNumber.Sub(seReceipt.BlockNumber, big.NewInt(256))) + helpers.PanicErr(err) + fmt.Println("blockhash stored by storeEarliest:", hexutil.Encode(bh[:])) + anchorBlockNumber = seReceipt.BlockNumber + } + if anchorBlockNumber == nil { + panic("no anchor block number") + } + + fmt.Println("\nexecuting store(n)") + latestHead, err := e.Ec.HeaderByNumber(context.Background(), nil) + helpers.PanicErr(err) + toStore := latestHead.Number.Sub(latestHead.Number, big.NewInt(1)) + tx, err = bhs.Store(e.Owner, toStore) + helpers.PanicErr(err) + sReceipt := helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, "store on", bhsContractAddress.String()) + if sReceipt.Status != 1 { + fmt.Println("store failed") + os.Exit(1) + } else { + fmt.Println("store succeeded, checking BH is there") + bh, err := bhs.GetBlockhash(nil, toStore) + helpers.PanicErr(err) + fmt.Println("blockhash stored by store:", hexutil.Encode(bh[:])) + } + + fmt.Println("\nexecuting storeVerifyHeader") + headers, _, err := helpers.GetRlpHeaders(e, []*big.Int{anchorBlockNumber}, false) + helpers.PanicErr(err) + + toStore = anchorBlockNumber.Sub(anchorBlockNumber, big.NewInt(1)) + tx, err = bhs.StoreVerifyHeader(e.Owner, toStore, headers[0]) + helpers.PanicErr(err) + svhReceipt := helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, "storeVerifyHeader on", bhsContractAddress.String()) + if svhReceipt.Status != 1 { + fmt.Println("storeVerifyHeader failed") + os.Exit(1) + } else { + fmt.Println("storeVerifyHeader succeeded, checking BH is there") + bh, err := bhs.GetBlockhash(nil, toStore) + helpers.PanicErr(err) + fmt.Println("blockhash stored by storeVerifyHeader:", hexutil.Encode(bh[:])) + } +} + +func sendTx(e helpers.Environment, to common.Address, data []byte) (*types.Receipt, common.Hash) { + nonce, err := e.Ec.PendingNonceAt(context.Background(), e.Owner.From) + helpers.PanicErr(err) + gasPrice, err := e.Ec.SuggestGasPrice(context.Background()) + helpers.PanicErr(err) + rawTx := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + To: &to, + Data: data, + Value: big.NewInt(0), + Gas: 1_000_000, + GasPrice: gasPrice, + }) + signedTx, err := e.Owner.Signer(e.Owner.From, rawTx) + helpers.PanicErr(err) + err = e.Ec.SendTransaction(context.Background(), signedTx) + helpers.PanicErr(err) + return helpers.ConfirmTXMined(context.Background(), e.Ec, signedTx, + e.ChainID, "send tx", signedTx.Hash().String(), "to", to.String()), signedTx.Hash() +} + func deployUniverse(e helpers.Environment) { deployCmd := flag.NewFlagSet("deploy-universe", flag.ExitOnError) @@ -132,7 +558,7 @@ func deployUniverse(e helpers.Environment) { fmt.Println("\nDeploying Coordinator...") coordinatorAddress = deployCoordinator(e, *linkAddress, bhsContractAddress.String(), *linkEthAddress) - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(coordinatorAddress, e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(coordinatorAddress, e.Ec) helpers.PanicErr(err) fmt.Println("\nDeploying Batch Coordinator...") @@ -147,9 +573,9 @@ func deployUniverse(e helpers.Environment) { uint32(*stalenessSeconds), uint32(*gasAfterPayment), fallbackWeiPerUnitLink, - vrf_coordinator_v2plus.VRFCoordinatorV2PlusFeeConfig{ - FulfillmentFlatFeeLinkPPM: uint32(*flatFeeLinkPPM), - FulfillmentFlatFeeEthPPM: uint32(*flatFeeEthPPM), + vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig{ + FulfillmentFlatFeeLinkPPM: uint32(*flatFeeLinkPPM), + FulfillmentFlatFeeNativePPM: uint32(*flatFeeEthPPM), }, ) @@ -264,7 +690,7 @@ func deployWrapperUniverse(e helpers.Environment) { common.HexToAddress(*linkAddress), wrapper) - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(common.HexToAddress(*coordinatorAddress), e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(common.HexToAddress(*coordinatorAddress), e.Ec) helpers.PanicErr(err) eoaFundSubscription(e, *coordinator, *linkAddress, amount, subID) diff --git a/core/scripts/vrfv2plus/testnet/util.go b/core/scripts/vrfv2plus/testnet/util.go index d002b8c03b..904a3f6ba4 100644 --- a/core/scripts/vrfv2plus/testnet/util.go +++ b/core/scripts/vrfv2plus/testnet/util.go @@ -15,7 +15,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/vrf_coordinator_v2plus" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_sub_owner" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_consumer_example" @@ -40,7 +40,7 @@ func deployCoordinator( bhsAddress string, linkEthAddress string, ) (coordinatorAddress common.Address) { - _, tx, _, err := vrf_coordinator_v2plus.DeployVRFCoordinatorV2Plus( + _, tx, _, err := vrf_coordinator_v2_5.DeployVRFCoordinatorV25( e.Owner, e.Ec, common.HexToAddress(bhsAddress)) @@ -48,10 +48,10 @@ func deployCoordinator( coordinatorAddress = helpers.ConfirmContractDeployed(context.Background(), e.Ec, tx, e.ChainID) // Set LINK and LINK ETH - coordinator, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(coordinatorAddress, e.Ec) + coordinator, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(coordinatorAddress, e.Ec) helpers.PanicErr(err) - linkTx, err := coordinator.SetLINKAndLINKETHFeed(e.Owner, + linkTx, err := coordinator.SetLINKAndLINKNativeFeed(e.Owner, common.HexToAddress(linkAddress), common.HexToAddress(linkEthAddress)) helpers.PanicErr(err) helpers.ConfirmTXMined(context.Background(), e.Ec, linkTx, e.ChainID) @@ -65,20 +65,20 @@ func deployBatchCoordinatorV2(e helpers.Environment, coordinatorAddress common.A } func eoaAddConsumerToSub(e helpers.Environment, - coordinator vrf_coordinator_v2plus.VRFCoordinatorV2Plus, subID *big.Int, consumerAddress string) { + coordinator vrf_coordinator_v2_5.VRFCoordinatorV25, subID *big.Int, 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_v2plus.VRFCoordinatorV2Plus) { +func eoaCreateSub(e helpers.Environment, coordinator vrf_coordinator_v2_5.VRFCoordinatorV25) { tx, err := coordinator.CreateSubscription(e.Owner) helpers.PanicErr(err) helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID) } // returns subscription ID that belongs to the given owner. Returns result found first -func findSubscriptionID(e helpers.Environment, coordinator *vrf_coordinator_v2plus.VRFCoordinatorV2Plus) *big.Int { +func findSubscriptionID(e helpers.Environment, coordinator *vrf_coordinator_v2_5.VRFCoordinatorV25) *big.Int { // Use most recent 500 blocks as search window. head, err := e.Ec.BlockNumber(context.Background()) helpers.PanicErr(err) @@ -109,7 +109,7 @@ func eoaDeployConsumer(e helpers.Environment, } func eoaFundSubscription(e helpers.Environment, - coordinator vrf_coordinator_v2plus.VRFCoordinatorV2Plus, linkAddress string, amount, subID *big.Int) { + coordinator vrf_coordinator_v2_5.VRFCoordinatorV25, linkAddress string, amount, subID *big.Int) { linkToken, err := link_token_interface.NewLinkToken(common.HexToAddress(linkAddress), e.Ec) helpers.PanicErr(err) bal, err := linkToken.BalanceOf(nil, e.Owner.From) @@ -122,7 +122,7 @@ func eoaFundSubscription(e helpers.Environment, helpers.ConfirmTXMined(context.Background(), e.Ec, tx, e.ChainID, fmt.Sprintf("sub ID: %d", subID)) } -func printCoordinatorConfig(coordinator *vrf_coordinator_v2plus.VRFCoordinatorV2Plus) { +func printCoordinatorConfig(coordinator *vrf_coordinator_v2_5.VRFCoordinatorV25) { cfg, err := coordinator.SConfig(nil) helpers.PanicErr(err) @@ -135,13 +135,13 @@ func printCoordinatorConfig(coordinator *vrf_coordinator_v2plus.VRFCoordinatorV2 func setCoordinatorConfig( e helpers.Environment, - coordinator vrf_coordinator_v2plus.VRFCoordinatorV2Plus, + coordinator vrf_coordinator_v2_5.VRFCoordinatorV25, minConfs uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPayment uint32, fallbackWeiPerUnitLink *big.Int, - feeConfig vrf_coordinator_v2plus.VRFCoordinatorV2PlusFeeConfig, + feeConfig vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig, ) { tx, err := coordinator.SetConfig( e.Owner, @@ -157,7 +157,7 @@ func setCoordinatorConfig( } func registerCoordinatorProvingKey(e helpers.Environment, - coordinator vrf_coordinator_v2plus.VRFCoordinatorV2Plus, uncompressed string, oracleAddress string) { + coordinator vrf_coordinator_v2_5.VRFCoordinatorV25, uncompressed string, oracleAddress string) { pubBytes, err := hex.DecodeString(uncompressed) helpers.PanicErr(err) pk, err := crypto.UnmarshalPubkey(pubBytes) diff --git a/core/services/blockhashstore/common.go b/core/services/blockhashstore/common.go index 61aaf98929..677016253f 100644 --- a/core/services/blockhashstore/common.go +++ b/core/services/blockhashstore/common.go @@ -33,6 +33,8 @@ type Event struct { } // BHS defines an interface for interacting with a BlockhashStore contract. +// +//go:generate mockery --quiet --name BHS --output ./mocks/ --case=underscore type BHS interface { // Store the hash associated with blockNum. Store(ctx context.Context, blockNum uint64) error diff --git a/core/services/blockhashstore/coordinators.go b/core/services/blockhashstore/coordinators.go index 1a8588dbbb..ff5aff1f5e 100644 --- a/core/services/blockhashstore/coordinators.go +++ b/core/services/blockhashstore/coordinators.go @@ -11,7 +11,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" v1 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface" v2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" - v2plus "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" + v2plus "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) @@ -246,17 +246,17 @@ func (v *V2Coordinator) Fulfillments(ctx context.Context, fromBlock uint64) ([]E // V2PlusCoordinator fetches request and fulfillment logs from a VRF V2Plus coordinator contract. type V2PlusCoordinator struct { - c v2plus.VRFCoordinatorV2PlusInterface + c v2plus.IVRFCoordinatorV2PlusInternalInterface lp logpoller.LogPoller } // NewV2Coordinator creates a new V2Coordinator from the given contract. -func NewV2PlusCoordinator(c v2plus.VRFCoordinatorV2PlusInterface, lp logpoller.LogPoller) (*V2PlusCoordinator, error) { +func NewV2PlusCoordinator(c v2plus.IVRFCoordinatorV2PlusInternalInterface, lp logpoller.LogPoller) (*V2PlusCoordinator, error) { err := lp.RegisterFilter(logpoller.Filter{ Name: logpoller.FilterName("VRFv2PlusCoordinatorFeeder", c.Address()), EventSigs: []common.Hash{ - v2plus.VRFCoordinatorV2PlusRandomWordsRequested{}.Topic(), - v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled{}.Topic(), + v2plus.IVRFCoordinatorV2PlusInternalRandomWordsRequested{}.Topic(), + v2plus.IVRFCoordinatorV2PlusInternalRandomWordsFulfilled{}.Topic(), }, Addresses: []common.Address{c.Address()}, }) @@ -277,7 +277,7 @@ func (v *V2PlusCoordinator) Requests( int64(fromBlock), int64(toBlock), []common.Hash{ - v2plus.VRFCoordinatorV2PlusRandomWordsRequested{}.Topic(), + v2plus.IVRFCoordinatorV2PlusInternalRandomWordsRequested{}.Topic(), }, v.c.Address(), pg.WithParentCtx(ctx)) @@ -291,7 +291,7 @@ func (v *V2PlusCoordinator) Requests( if err != nil { continue // malformed log should not break flow } - request, ok := requestLog.(*v2plus.VRFCoordinatorV2PlusRandomWordsRequested) + request, ok := requestLog.(*v2plus.IVRFCoordinatorV2PlusInternalRandomWordsRequested) if !ok { continue // malformed log should not break flow } @@ -312,7 +312,7 @@ func (v *V2PlusCoordinator) Fulfillments(ctx context.Context, fromBlock uint64) int64(fromBlock), int64(toBlock), []common.Hash{ - v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled{}.Topic(), + v2plus.IVRFCoordinatorV2PlusInternalRandomWordsFulfilled{}.Topic(), }, v.c.Address(), pg.WithParentCtx(ctx)) @@ -326,7 +326,7 @@ func (v *V2PlusCoordinator) Fulfillments(ctx context.Context, fromBlock uint64) if err != nil { continue // malformed log should not break flow } - request, ok := requestLog.(*v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled) + request, ok := requestLog.(*v2plus.IVRFCoordinatorV2PlusInternalRandomWordsFulfilled) if !ok { continue // malformed log should not break flow } diff --git a/core/services/blockhashstore/delegate.go b/core/services/blockhashstore/delegate.go index 0342dff78b..ccd4d3463f 100644 --- a/core/services/blockhashstore/delegate.go +++ b/core/services/blockhashstore/delegate.go @@ -3,6 +3,7 @@ package blockhashstore import ( "context" "fmt" + "sync" "time" "github.com/pkg/errors" @@ -12,7 +13,7 @@ import ( 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" + v2plus "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" @@ -127,8 +128,8 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC coordinators = append(coordinators, coord) } if jb.BlockhashStoreSpec.CoordinatorV2PlusAddress != nil { - var c *v2plus.VRFCoordinatorV2Plus - if c, err = v2plus.NewVRFCoordinatorV2Plus( + var c v2plus.IVRFCoordinatorV2PlusInternalInterface + if c, err = v2plus.NewIVRFCoordinatorV2PlusInternal( jb.BlockhashStoreSpec.CoordinatorV2PlusAddress.Address(), chain.Client()); err != nil { return nil, errors.Wrap(err, "building V2Plus coordinator") @@ -165,6 +166,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC jb.BlockhashStoreSpec.TrustedBlockhashStoreBatchSize, int(jb.BlockhashStoreSpec.WaitBlocks), int(jb.BlockhashStoreSpec.LookbackBlocks), + jb.BlockhashStoreSpec.HeartbeatPeriod, func(ctx context.Context) (uint64, error) { head, err := lp.LatestBlock(pg.WithParentCtx(ctx)) if err != nil { @@ -178,7 +180,6 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC pollPeriod: jb.BlockhashStoreSpec.PollPeriod, runTimeout: jb.BlockhashStoreSpec.RunTimeout, logger: log, - done: make(chan struct{}), }}, nil } @@ -198,7 +199,7 @@ func (d *Delegate) OnDeleteJob(spec job.Job, q pg.Queryer) error { return nil } type service struct { utils.StartStopOnce feeder *Feeder - done chan struct{} + wg sync.WaitGroup pollPeriod time.Duration runTimeout time.Duration logger logger.Logger @@ -212,8 +213,13 @@ func (s *service) Start(context.Context) error { s.logger.Infow("Starting BHS feeder") ticker := time.NewTicker(utils.WithJitter(s.pollPeriod)) s.parentCtx, s.cancel = context.WithCancel(context.Background()) + s.wg.Add(2) go func() { - defer close(s.done) + defer s.wg.Done() + s.feeder.StartHeartbeats(s.parentCtx, &realTimer{}) + }() + go func() { + defer s.wg.Done() defer ticker.Stop() for { select { @@ -233,7 +239,7 @@ func (s *service) Close() error { return s.StopOnce("BHS Feeder Service", func() error { s.logger.Infow("Stopping BHS feeder") s.cancel() - <-s.done + s.wg.Wait() return nil }) } diff --git a/core/services/blockhashstore/feeder.go b/core/services/blockhashstore/feeder.go index 14e51e6839..8cc607db9b 100644 --- a/core/services/blockhashstore/feeder.go +++ b/core/services/blockhashstore/feeder.go @@ -2,6 +2,7 @@ package blockhashstore import ( "context" + "fmt" "sync" "time" @@ -25,6 +26,7 @@ func NewFeeder( trustedBHSBatchSize int32, waitBlocks int, lookbackBlocks int, + heartbeatPeriod time.Duration, latestBlock func(ctx context.Context) (uint64, error), ) *Feeder { return &Feeder{ @@ -40,6 +42,7 @@ func NewFeeder( storedTrusted: make(map[uint64]common.Hash), lastRunBlock: 0, wgStored: sync.WaitGroup{}, + heartbeatPeriod: heartbeatPeriod, } } @@ -55,6 +58,12 @@ type Feeder struct { lookbackBlocks int latestBlock func(ctx context.Context) (uint64, error) + // heartbeatPeriodTime is a heartbeat period in seconds by which + // the feeder will always store a blockhash, even if there are no + // unfulfilled requests. This is to ensure that there are blockhashes + // in the store to start from if we ever need to run backwards mode. + heartbeatPeriod time.Duration + stored map[uint64]struct{} // used for trustless feeder storedTrusted map[uint64]common.Hash // used for trusted feeder lastRunBlock uint64 @@ -63,6 +72,40 @@ type Feeder struct { errsLock sync.Mutex } +//go:generate mockery --quiet --name Timer --output ./mocks/ --case=underscore +type Timer interface { + After(d time.Duration) <-chan time.Time +} + +type realTimer struct{} + +func (r *realTimer) After(d time.Duration) <-chan time.Time { + return time.After(d) +} + +func (f *Feeder) StartHeartbeats(ctx context.Context, timer Timer) { + if f.heartbeatPeriod == 0 { + f.lggr.Infow("Not starting heartbeat blockhash using storeEarliest") + return + } + f.lggr.Infow(fmt.Sprintf("Starting heartbeat blockhash using storeEarliest every %s", f.heartbeatPeriod.String())) + for { + after := timer.After(f.heartbeatPeriod) + select { + case <-after: + f.lggr.Infow("storing heartbeat blockhash using storeEarliest", + "heartbeatPeriodSeconds", f.heartbeatPeriod.Seconds()) + if err := f.bhs.StoreEarliest(ctx); err != nil { + f.lggr.Infow("failed to store heartbeat blockhash using storeEarliest", + "heartbeatPeriodSeconds", f.heartbeatPeriod.Seconds(), + "err", err) + } + case <-ctx.Done(): + return + } + } +} + // Run the feeder. func (f *Feeder) Run(ctx context.Context) error { latestBlock, err := f.latestBlock(ctx) diff --git a/core/services/blockhashstore/feeder_test.go b/core/services/blockhashstore/feeder_test.go index e015253ba2..3145a9fd76 100644 --- a/core/services/blockhashstore/feeder_test.go +++ b/core/services/blockhashstore/feeder_test.go @@ -2,8 +2,10 @@ package blockhashstore import ( "context" + "fmt" "math/big" "testing" + "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" @@ -17,47 +19,34 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils/mathutil" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + bhsmocks "github.com/smartcontractkit/chainlink/v2/core/services/blockhashstore/mocks" "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/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" + loggermocks "github.com/smartcontractkit/chainlink/v2/core/logger/mocks" ) const ( // VRF-only events. - randomWordsRequestedV2Plus string = "RandomWordsRequested" - randomWordsFulfilledV2Plus string = "RandomWordsFulfilled" - randomWordsRequestedV2 string = "RandomWordsRequested" - randomWordsFulfilledV2 string = "RandomWordsFulfilled" - randomWordsRequestedV1 string = "RandomnessRequest" - randomWordsFulfilledV1 string = "RandomnessRequestFulfilled" - randomnessFulfillmentRequestedEvent string = "RandomnessFulfillmentRequested" - randomWordsFulfilledEvent string = "RandomWordsFulfilled" - newTransmissionEvent string = "NewTransmission" - outputsServedEvent string = "OutputsServed" + randomWordsRequestedV2Plus string = "RandomWordsRequested" + randomWordsFulfilledV2Plus string = "RandomWordsFulfilled" + randomWordsRequestedV2 string = "RandomWordsRequested" + randomWordsFulfilledV2 string = "RandomWordsFulfilled" + randomWordsRequestedV1 string = "RandomnessRequest" + randomWordsFulfilledV1 string = "RandomnessRequestFulfilled" ) var ( - vrfCoordinatorV2PlusABI = evmtypes.MustGetABI(vrf_coordinator_v2plus.VRFCoordinatorV2PlusMetaData.ABI) + vrfCoordinatorV2PlusABI = evmtypes.MustGetABI(vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalMetaData.ABI) vrfCoordinatorV2ABI = evmtypes.MustGetABI(vrf_coordinator_v2.VRFCoordinatorV2MetaData.ABI) vrfCoordinatorV1ABI = evmtypes.MustGetABI(solidity_vrf_coordinator_interface.VRFCoordinatorMetaData.ABI) _ Coordinator = &TestCoordinator{} _ BHS = &TestBHS{} - tests = []struct { - name string - requests []Event - fulfillments []Event - wait int - lookback int - latest uint64 - bhs TestBHS - expectedStored []uint64 - expectedStoredMapBlocks []uint64 // expected state of stored map in Feeder struct - expectedErrMsg string - }{ + tests = []testCase{ { name: "single unfulfilled request", requests: []Event{{Block: 150, ID: "1000"}}, @@ -236,323 +225,467 @@ var ( } ) -func TestFeeder(t *testing.T) { +func TestStartHeartbeats(t *testing.T) { + t.Run("bhs_heartbeat_happy_path", func(t *testing.T) { + expectedDuration := 600 * time.Second + mockBHS := bhsmocks.NewBHS(t) + mockLogger := loggermocks.NewLogger(t) + feeder := NewFeeder( + mockLogger, + &TestCoordinator{}, // Not used for this test + mockBHS, + &mocklp.LogPoller{}, // Not used for this test + 0, + 25, // Not used for this test + 100, // Not used for this test + expectedDuration, + func(ctx context.Context) (uint64, error) { + return tests[0].latest, nil + }) + + ctx, cancel := context.WithCancel(testutils.Context(t)) + mockTimer := bhsmocks.NewTimer(t) + + mockBHS.On("StoreEarliest", ctx).Return(nil).Once() + mockTimer.On("After", expectedDuration).Return(func() <-chan time.Time { + c := make(chan time.Time) + close(c) + return c + }()).Once() + mockTimer.On("After", expectedDuration).Return(func() <-chan time.Time { + c := make(chan time.Time) + return c + }()).Run(func(args mock.Arguments) { + cancel() + }).Once() + mockLogger.On("Infow", "Starting heartbeat blockhash using storeEarliest every 10m0s").Once() + mockLogger.On("Infow", "storing heartbeat blockhash using storeEarliest", + "heartbeatPeriodSeconds", expectedDuration.Seconds()).Once() + require.Len(t, mockLogger.ExpectedCalls, 2) + require.Len(t, mockTimer.ExpectedCalls, 2) + defer mockTimer.AssertExpectations(t) + defer mockBHS.AssertExpectations(t) + defer mockLogger.AssertExpectations(t) + + feeder.StartHeartbeats(ctx, mockTimer) + }) + + t.Run("bhs_heartbeat_sad_path_store_earliest_err", func(t *testing.T) { + expectedDuration := 600 * time.Second + expectedError := fmt.Errorf("insufficient gas") + mockBHS := bhsmocks.NewBHS(t) + mockLogger := loggermocks.NewLogger(t) + feeder := NewFeeder( + mockLogger, + &TestCoordinator{}, // Not used for this test + mockBHS, + &mocklp.LogPoller{}, // Not used for this test + 0, + 25, // Not used for this test + 100, // Not used for this test + expectedDuration, + func(ctx context.Context) (uint64, error) { + return tests[0].latest, nil + }) + + ctx, cancel := context.WithCancel(testutils.Context(t)) + mockTimer := bhsmocks.NewTimer(t) + + mockBHS.On("StoreEarliest", ctx).Return(expectedError).Once() + mockTimer.On("After", expectedDuration).Return(func() <-chan time.Time { + c := make(chan time.Time) + close(c) + return c + }()).Once() + mockTimer.On("After", expectedDuration).Return(func() <-chan time.Time { + c := make(chan time.Time) + return c + }()).Run(func(args mock.Arguments) { + cancel() + }).Once() + mockLogger.On("Infow", "Starting heartbeat blockhash using storeEarliest every 10m0s").Once() + mockLogger.On("Infow", "storing heartbeat blockhash using storeEarliest", + "heartbeatPeriodSeconds", expectedDuration.Seconds()).Once() + mockLogger.On("Infow", "failed to store heartbeat blockhash using storeEarliest", + "heartbeatPeriodSeconds", expectedDuration.Seconds(), + "err", expectedError).Once() + require.Len(t, mockLogger.ExpectedCalls, 3) + require.Len(t, mockTimer.ExpectedCalls, 2) + defer mockTimer.AssertExpectations(t) + defer mockBHS.AssertExpectations(t) + defer mockLogger.AssertExpectations(t) + + feeder.StartHeartbeats(ctx, mockTimer) + }) + + t.Run("bhs_heartbeat_sad_path_heartbeat_0", func(t *testing.T) { + expectedDuration := 0 * time.Second + mockBHS := bhsmocks.NewBHS(t) + mockLogger := loggermocks.NewLogger(t) + feeder := NewFeeder( + mockLogger, + &TestCoordinator{}, // Not used for this test + mockBHS, + &mocklp.LogPoller{}, // Not used for this test + 0, + 25, // Not used for this test + 100, // Not used for this test + expectedDuration, + func(ctx context.Context) (uint64, error) { + return tests[0].latest, nil + }) + + mockTimer := bhsmocks.NewTimer(t) + mockLogger.On("Infow", "Not starting heartbeat blockhash using storeEarliest").Once() + require.Len(t, mockLogger.ExpectedCalls, 1) + require.Len(t, mockBHS.ExpectedCalls, 0) + require.Len(t, mockTimer.ExpectedCalls, 0) + defer mockTimer.AssertExpectations(t) + defer mockBHS.AssertExpectations(t) + defer mockLogger.AssertExpectations(t) + + feeder.StartHeartbeats(testutils.Context(t), mockTimer) + }) +} + +type testCase struct { + name string + requests []Event + fulfillments []Event + wait int + lookback int + latest uint64 + bhs TestBHS + expectedStored []uint64 + expectedStoredMapBlocks []uint64 // expected state of stored map in Feeder struct + expectedErrMsg string +} +func TestFeeder(t *testing.T) { for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - coordinator := &TestCoordinator{ - RequestEvents: test.requests, - 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) { - return test.latest, nil - }) - - 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) - require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) + t.Run(test.name, test.testFeeder) + } +} + +func (test testCase) testFeeder(t *testing.T) { + coordinator := &TestCoordinator{ + RequestEvents: test.requests, + FulfillmentEvents: test.fulfillments, + } + + lp := &mocklp.LogPoller{} + feeder := NewFeeder( + logger.TestLogger(t), + coordinator, + &test.bhs, + lp, + 0, + test.wait, + test.lookback, + 600*time.Second, + func(ctx context.Context) (uint64, error) { + return test.latest, nil }) + + 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) + require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) } func TestFeederWithLogPollerVRFv1(t *testing.T) { + for _, test := range tests { + t.Run(test.name, test.testFeederWithLogPollerVRFv1) + } +} +func (test testCase) testFeederWithLogPollerVRFv1(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 := solidity_vrf_coordinator_interface.NewVRFCoordinator(coordinatorAddress, nil) - require.NoError(t, err) - coordinator := &V1Coordinator{ - 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 - } - requestLogs = append( - requestLogs, - newRandomnessRequestedLogV1(t, r.Block, r.ID, coordinatorAddress), - ) - } - - // Construct fulfillment logs. - var fulfillmentLogs []logpoller.Log - for _, r := range test.fulfillments { - fulfillmentLogs = append( - fulfillmentLogs, - newRandomnessFulfilledLogV1(t, r.Block, r.ID, coordinatorAddress), - ) - } - - // Mock log poller. - lp.On("LatestBlock", mock.Anything). - Return(latest, nil) - lp.On( - "LogsWithSigs", - fromBlock, - toBlock, - []common.Hash{ - solidity_vrf_coordinator_interface.VRFCoordinatorRandomnessRequest{}.Topic(), - }, - coordinatorAddress, - mock.Anything, - ).Return(requestLogs, nil) - lp.On( - "LogsWithSigs", - fromBlock, - latest, - []common.Hash{ - solidity_vrf_coordinator_interface.VRFCoordinatorRandomnessRequestFulfilled{}.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) { - 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) - require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) + // Instantiate log poller & coordinator. + lp := &mocklp.LogPoller{} + lp.On("RegisterFilter", mock.Anything).Return(nil) + c, err := solidity_vrf_coordinator_interface.NewVRFCoordinator(coordinatorAddress, nil) + require.NoError(t, err) + coordinator := &V1Coordinator{ + 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 + } + requestLogs = append( + requestLogs, + newRandomnessRequestedLogV1(t, r.Block, r.ID, coordinatorAddress), + ) + } + + // Construct fulfillment logs. + var fulfillmentLogs []logpoller.Log + for _, r := range test.fulfillments { + fulfillmentLogs = append( + fulfillmentLogs, + newRandomnessFulfilledLogV1(t, r.Block, r.ID, coordinatorAddress), + ) + } + + // Mock log poller. + lp.On("LatestBlock", mock.Anything). + Return(latest, nil) + lp.On( + "LogsWithSigs", + fromBlock, + toBlock, + []common.Hash{ + solidity_vrf_coordinator_interface.VRFCoordinatorRandomnessRequest{}.Topic(), + }, + coordinatorAddress, + mock.Anything, + ).Return(requestLogs, nil) + lp.On( + "LogsWithSigs", + fromBlock, + latest, + []common.Hash{ + solidity_vrf_coordinator_interface.VRFCoordinatorRandomnessRequestFulfilled{}.Topic(), + }, + coordinatorAddress, + mock.Anything, + ).Return(fulfillmentLogs, nil) + + // Instantiate feeder. + feeder := NewFeeder( + logger.TestLogger(t), + coordinator, + &test.bhs, + lp, + 0, + test.wait, + test.lookback, + 600*time.Second, + 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) + require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) } func TestFeederWithLogPollerVRFv2(t *testing.T) { + for _, test := range tests { + t.Run(test.name, test.testFeederWithLogPollerVRFv2) + } +} +func (test testCase) testFeederWithLogPollerVRFv2(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_v2.NewVRFCoordinatorV2(coordinatorAddress, nil) - require.NoError(t, err) - coordinator := &V2Coordinator{ - 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, - newRandomnessRequestedLogV2(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, - newRandomnessFulfilledLogV2(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_v2.VRFCoordinatorV2RandomWordsRequested{}.Topic(), - }, - coordinatorAddress, - mock.Anything, - ).Return(requestLogs, nil) - lp.On( - "LogsWithSigs", - fromBlock, - latest, - []common.Hash{ - vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled{}.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) { - 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) - require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) + // Instantiate log poller & coordinator. + lp := &mocklp.LogPoller{} + lp.On("RegisterFilter", mock.Anything).Return(nil) + c, err := vrf_coordinator_v2.NewVRFCoordinatorV2(coordinatorAddress, nil) + require.NoError(t, err) + coordinator := &V2Coordinator{ + 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, + newRandomnessRequestedLogV2(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, + newRandomnessFulfilledLogV2(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_v2.VRFCoordinatorV2RandomWordsRequested{}.Topic(), + }, + coordinatorAddress, + mock.Anything, + ).Return(requestLogs, nil) + lp.On( + "LogsWithSigs", + fromBlock, + latest, + []common.Hash{ + vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled{}.Topic(), + }, + coordinatorAddress, + mock.Anything, + ).Return(fulfillmentLogs, nil) + + // Instantiate feeder. + feeder := NewFeeder( + logger.TestLogger(t), + coordinator, + &test.bhs, + lp, + 0, + test.wait, + test.lookback, + 600*time.Second, + 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) + require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) } func TestFeederWithLogPollerVRFv2Plus(t *testing.T) { + for _, test := range tests { + t.Run(test.name, test.testFeederWithLogPollerVRFv2Plus) + } +} +func (test testCase) 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) { - 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) - require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) + // Instantiate log poller & coordinator. + lp := &mocklp.LogPoller{} + lp.On("RegisterFilter", mock.Anything).Return(nil) + c, err := vrf_coordinator_v2plus_interface.NewIVRFCoordinatorV2PlusInternal(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_interface.IVRFCoordinatorV2PlusInternalRandomWordsRequested{}.Topic(), + }, + coordinatorAddress, + mock.Anything, + ).Return(requestLogs, nil) + lp.On( + "LogsWithSigs", + fromBlock, + latest, + []common.Hash{ + vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRandomWordsFulfilled{}.Topic(), + }, + coordinatorAddress, + mock.Anything, + ).Return(fulfillmentLogs, nil) + + // Instantiate feeder. + feeder := NewFeeder( + logger.TestLogger(t), + coordinator, + &test.bhs, + lp, + 0, + test.wait, + test.lookback, + 600*time.Second, + 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) + require.ElementsMatch(t, test.expectedStoredMapBlocks, maps.Keys(feeder.stored)) } func TestFeeder_CachesStoredBlocks(t *testing.T) { @@ -571,6 +704,7 @@ func TestFeeder_CachesStoredBlocks(t *testing.T) { 0, 100, 200, + 600*time.Second, func(ctx context.Context) (uint64, error) { return 250, nil }) @@ -833,7 +967,7 @@ func newRandomnessRequestedLogV2Plus( requestID *big.Int, coordinatorAddress common.Address, ) logpoller.Log { - e := vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested{ + e := vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRandomWordsRequested{ RequestId: requestID, PreSeed: big.NewInt(0), MinimumRequestConfirmations: 0, @@ -921,7 +1055,7 @@ func newRandomnessFulfilledLogV2Plus( requestID *big.Int, coordinatorAddress common.Address, ) logpoller.Log { - e := vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled{ + e := vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRandomWordsFulfilled{ RequestId: requestID, OutputSeed: big.NewInt(0), Payment: big.NewInt(0), @@ -929,7 +1063,7 @@ func newRandomnessFulfilledLogV2Plus( Raw: types.Log{ BlockNumber: requestBlock, }, - SubID: big.NewInt(0), + SubId: big.NewInt(0), } var unindexed abi.Arguments for _, a := range vrfCoordinatorV2PlusABI.Events[randomWordsFulfilledV2Plus].Inputs { @@ -962,7 +1096,7 @@ func newRandomnessFulfilledLogV2Plus( topic1, err := requestIdArg.Pack(e.RequestId) require.NoError(t, err) - topic2, err := subIdArg.Pack(e.SubID) + topic2, err := subIdArg.Pack(e.SubId) require.NoError(t, err) topic0 := vrfCoordinatorV2PlusABI.Events[randomWordsFulfilledV2Plus].ID diff --git a/core/services/blockhashstore/mocks/bhs.go b/core/services/blockhashstore/mocks/bhs.go new file mode 100644 index 0000000000..bf01e80ffd --- /dev/null +++ b/core/services/blockhashstore/mocks/bhs.go @@ -0,0 +1,111 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" +) + +// BHS is an autogenerated mock type for the BHS type +type BHS struct { + mock.Mock +} + +// IsStored provides a mock function with given fields: ctx, blockNum +func (_m *BHS) IsStored(ctx context.Context, blockNum uint64) (bool, error) { + ret := _m.Called(ctx, blockNum) + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64) (bool, error)); ok { + return rf(ctx, blockNum) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64) bool); ok { + r0 = rf(ctx, blockNum) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok { + r1 = rf(ctx, blockNum) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// IsTrusted provides a mock function with given fields: +func (_m *BHS) IsTrusted() bool { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// Store provides a mock function with given fields: ctx, blockNum +func (_m *BHS) Store(ctx context.Context, blockNum uint64) error { + ret := _m.Called(ctx, blockNum) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, uint64) error); ok { + r0 = rf(ctx, blockNum) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// StoreEarliest provides a mock function with given fields: ctx +func (_m *BHS) StoreEarliest(ctx context.Context) error { + ret := _m.Called(ctx) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = rf(ctx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// StoreTrusted provides a mock function with given fields: ctx, blockNums, blockhashes, recentBlock, recentBlockhash +func (_m *BHS) StoreTrusted(ctx context.Context, blockNums []uint64, blockhashes []common.Hash, recentBlock uint64, recentBlockhash common.Hash) error { + ret := _m.Called(ctx, blockNums, blockhashes, recentBlock, recentBlockhash) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []uint64, []common.Hash, uint64, common.Hash) error); ok { + r0 = rf(ctx, blockNums, blockhashes, recentBlock, recentBlockhash) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +type mockConstructorTestingTNewBHS interface { + mock.TestingT + Cleanup(func()) +} + +// NewBHS creates a new instance of BHS. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewBHS(t mockConstructorTestingTNewBHS) *BHS { + mock := &BHS{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/blockhashstore/mocks/timer.go b/core/services/blockhashstore/mocks/timer.go new file mode 100644 index 0000000000..722cd35f27 --- /dev/null +++ b/core/services/blockhashstore/mocks/timer.go @@ -0,0 +1,45 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package mocks + +import ( + time "time" + + mock "github.com/stretchr/testify/mock" +) + +// Timer is an autogenerated mock type for the Timer type +type Timer struct { + mock.Mock +} + +// After provides a mock function with given fields: d +func (_m *Timer) After(d time.Duration) <-chan time.Time { + ret := _m.Called(d) + + var r0 <-chan time.Time + if rf, ok := ret.Get(0).(func(time.Duration) <-chan time.Time); ok { + r0 = rf(d) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan time.Time) + } + } + + return r0 +} + +type mockConstructorTestingTNewTimer interface { + mock.TestingT + Cleanup(func()) +} + +// NewTimer creates a new instance of Timer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewTimer(t mockConstructorTestingTNewTimer) *Timer { + mock := &Timer{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/blockhashstore/validate.go b/core/services/blockhashstore/validate.go index 157f6f2ec0..82b813a37f 100644 --- a/core/services/blockhashstore/validate.go +++ b/core/services/blockhashstore/validate.go @@ -68,6 +68,10 @@ func ValidatedSpec(tomlString string) (job.Job, error) { if spec.RunTimeout == 0 { spec.RunTimeout = 30 * time.Second } + if spec.HeartbeatPeriod < 0 { + return jb, errors.New(`"heartbeatPeriod" must be greater than 0`) + } + // spec.HeartbeatPeriodTime == 0, default is heartbeat disabled // Validation if spec.WaitBlocks >= spec.LookbackBlocks { diff --git a/core/services/blockhashstore/validate_test.go b/core/services/blockhashstore/validate_test.go index 10eaae10d3..0b7110a752 100644 --- a/core/services/blockhashstore/validate_test.go +++ b/core/services/blockhashstore/validate_test.go @@ -67,6 +67,27 @@ evmChainID = "4"`, require.NoError(t, err) require.Equal(t, int32(100), os.BlockhashStoreSpec.WaitBlocks) require.Equal(t, int32(200), os.BlockhashStoreSpec.LookbackBlocks) + require.Equal(t, time.Duration(0), os.BlockhashStoreSpec.HeartbeatPeriod) + require.Nil(t, os.BlockhashStoreSpec.FromAddresses) + require.Equal(t, 30*time.Second, os.BlockhashStoreSpec.PollPeriod) + require.Equal(t, 30*time.Second, os.BlockhashStoreSpec.RunTimeout) + }, + }, + { + name: "heartbeattimeset", + toml: ` +type = "blockhashstore" +name = "heartbeat-blocks-test" +coordinatorV1Address = "0x1F72B4A5DCf7CC6d2E38423bF2f4BFA7db97d139" +coordinatorV2Address = "0x2be990eE17832b59E0086534c5ea2459Aa75E38F" +blockhashStoreAddress = "0x3e20Cef636EdA7ba135bCbA4fe6177Bd3cE0aB17" +heartbeatPeriod = "650s" +evmChainID = "4"`, + assertion: func(t *testing.T, os job.Job, err error) { + require.NoError(t, err) + require.Equal(t, int32(100), os.BlockhashStoreSpec.WaitBlocks) + require.Equal(t, int32(200), os.BlockhashStoreSpec.LookbackBlocks) + require.Equal(t, time.Duration(650)*time.Second, os.BlockhashStoreSpec.HeartbeatPeriod) require.Nil(t, os.BlockhashStoreSpec.FromAddresses) require.Equal(t, 30*time.Second, os.BlockhashStoreSpec.PollPeriod) require.Equal(t, 30*time.Second, os.BlockhashStoreSpec.RunTimeout) diff --git a/core/services/blockheaderfeeder/block_header_feeder_test.go b/core/services/blockheaderfeeder/block_header_feeder_test.go index 0e52ee9447..6c1ec0946e 100644 --- a/core/services/blockheaderfeeder/block_header_feeder_test.go +++ b/core/services/blockheaderfeeder/block_header_feeder_test.go @@ -16,25 +16,27 @@ import ( keystoremocks "github.com/smartcontractkit/chainlink/v2/core/services/keystore/mocks" ) +type testCase struct { + name string + requests []blockhashstore.Event + fulfillments []blockhashstore.Event + wait int + lookback int + latest uint64 + alreadyStored []uint64 + expectedStored []uint64 + expectedErrMsg string + getBatchSize uint16 + storeBatchSize uint16 + getBatchCallCount uint16 + storeBatchCallCount uint16 + storedEarliest bool + bhs blockhashstore.TestBHS + batchBHS blockhashstore.TestBatchBHS +} + func TestFeeder(t *testing.T) { - tests := []struct { - name string - requests []blockhashstore.Event - fulfillments []blockhashstore.Event - wait int - lookback int - latest uint64 - alreadyStored []uint64 - expectedStored []uint64 - expectedErrMsg string - getBatchSize uint16 - storeBatchSize uint16 - getBatchCallCount uint16 - storeBatchCallCount uint16 - storedEarliest bool - bhs blockhashstore.TestBHS - batchBHS blockhashstore.TestBatchBHS - }{ + tests := []testCase{ { name: "single missing block", requests: []blockhashstore.Event{{Block: 150, ID: "request"}}, @@ -182,51 +184,55 @@ func TestFeeder(t *testing.T) { } for _, test := range tests { - lggr := logger.TestLogger(t) - lggr.Debugf("running test case: %s", test.name) - coordinator := &blockhashstore.TestCoordinator{ - RequestEvents: test.requests, - FulfillmentEvents: test.fulfillments, - } + t.Run(test.name, test.testFeeder) + } +} - test.batchBHS.Stored = append(test.batchBHS.Stored, test.alreadyStored...) +func (test testCase) testFeeder(t *testing.T) { + lggr := logger.TestLogger(t) + lggr.Debugf("running test case: %s", test.name) + coordinator := &blockhashstore.TestCoordinator{ + RequestEvents: test.requests, + FulfillmentEvents: test.fulfillments, + } - blockHeaderProvider := &blockhashstore.TestBlockHeaderProvider{} - fromAddress := "0x469aA2CD13e037DC5236320783dCfd0e641c0559" - fromAddresses := []ethkey.EIP55Address{(ethkey.EIP55Address(fromAddress))} - ks := keystoremocks.NewEth(t) - ks.On("GetRoundRobinAddress", testutils.FixtureChainID, mock.Anything).Maybe().Return(common.HexToAddress(fromAddress), nil) + test.batchBHS.Stored = append(test.batchBHS.Stored, test.alreadyStored...) - feeder := NewBlockHeaderFeeder( - lggr, - coordinator, - &test.bhs, - &test.batchBHS, - blockHeaderProvider, - test.wait, - test.lookback, - func(ctx context.Context) (uint64, error) { - return test.latest, nil - }, - ks, - test.getBatchSize, - test.storeBatchSize, - fromAddresses, - testutils.FixtureChainID, - ) + blockHeaderProvider := &blockhashstore.TestBlockHeaderProvider{} + fromAddress := "0x469aA2CD13e037DC5236320783dCfd0e641c0559" + fromAddresses := []ethkey.EIP55Address{ethkey.EIP55Address(fromAddress)} + ks := keystoremocks.NewEth(t) + ks.On("GetRoundRobinAddress", testutils.FixtureChainID, mock.Anything).Maybe().Return(common.HexToAddress(fromAddress), nil) - err := feeder.Run(testutils.Context(t)) - if test.expectedErrMsg == "" { - require.NoError(t, err) - } else { - require.EqualError(t, err, test.expectedErrMsg) - } + feeder := NewBlockHeaderFeeder( + lggr, + coordinator, + &test.bhs, + &test.batchBHS, + blockHeaderProvider, + test.wait, + test.lookback, + func(ctx context.Context) (uint64, error) { + return test.latest, nil + }, + ks, + test.getBatchSize, + test.storeBatchSize, + fromAddresses, + testutils.FixtureChainID, + ) - require.ElementsMatch(t, test.expectedStored, test.batchBHS.Stored) - require.Equal(t, test.storedEarliest, test.bhs.StoredEarliest) - require.Equal(t, test.getBatchCallCount, test.batchBHS.GetBlockhashesCallCounter) - require.Equal(t, test.storeBatchCallCount, test.batchBHS.StoreVerifyHeaderCallCounter) + 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.batchBHS.Stored) + require.Equal(t, test.storedEarliest, test.bhs.StoredEarliest) + require.Equal(t, test.getBatchCallCount, test.batchBHS.GetBlockhashesCallCounter) + require.Equal(t, test.storeBatchCallCount, test.batchBHS.StoreVerifyHeaderCallCounter) } func TestFeeder_CachesStoredBlocks(t *testing.T) { @@ -238,7 +244,7 @@ func TestFeeder_CachesStoredBlocks(t *testing.T) { batchBHS := &blockhashstore.TestBatchBHS{Stored: []uint64{75}} blockHeaderProvider := &blockhashstore.TestBlockHeaderProvider{} fromAddress := "0x469aA2CD13e037DC5236320783dCfd0e641c0559" - fromAddresses := []ethkey.EIP55Address{(ethkey.EIP55Address(fromAddress))} + fromAddresses := []ethkey.EIP55Address{ethkey.EIP55Address(fromAddress)} ks := keystoremocks.NewEth(t) ks.On("GetRoundRobinAddress", testutils.FixtureChainID, mock.Anything).Maybe().Return(common.HexToAddress(fromAddress), nil) diff --git a/core/services/blockheaderfeeder/delegate.go b/core/services/blockheaderfeeder/delegate.go index 2e80a874e5..2f37991f74 100644 --- a/core/services/blockheaderfeeder/delegate.go +++ b/core/services/blockheaderfeeder/delegate.go @@ -13,7 +13,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/blockhash_store" v1 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/solidity_vrf_coordinator_interface" v2 "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" - v2plus "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" + v2plus "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/blockhashstore" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -124,8 +124,8 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC coordinators = append(coordinators, coord) } if jb.BlockHeaderFeederSpec.CoordinatorV2PlusAddress != nil { - var c *v2plus.VRFCoordinatorV2Plus - if c, err = v2plus.NewVRFCoordinatorV2Plus( + var c v2plus.IVRFCoordinatorV2PlusInternalInterface + if c, err = v2plus.NewIVRFCoordinatorV2PlusInternal( jb.BlockHeaderFeederSpec.CoordinatorV2PlusAddress.Address(), chain.Client()); err != nil { return nil, errors.Wrap(err, "building V2 plus coordinator") diff --git a/core/services/chainlink/application.go b/core/services/chainlink/application.go index 7b4a4eac77..814c8a1c10 100644 --- a/core/services/chainlink/application.go +++ b/core/services/chainlink/application.go @@ -421,30 +421,26 @@ func NewApplication(opts ApplicationOpts) (Application, error) { } } - var feedsService feeds.Service = &feeds.NullService{} + var feedsService feeds.Service if cfg.Feature().FeedsManager() { - if keys, err := opts.KeyStore.CSA().GetAll(); err != nil { - globalLogger.Warn("[Feeds Service] Unable to start without CSA key", "err", err) - } else if len(keys) == 0 { - globalLogger.Warn("[Feeds Service] Unable to start without CSA key") - } else { - feedsORM := feeds.NewORM(db, opts.Logger, cfg.Database()) - feedsService = feeds.NewService( - feedsORM, - jobORM, - db, - jobSpawner, - keyStore, - cfg.Insecure(), - cfg.JobPipeline(), - cfg.OCR(), - cfg.OCR2(), - cfg.Database(), - legacyEVMChains, - globalLogger, - opts.Version, - ) - } + feedsORM := feeds.NewORM(db, opts.Logger, cfg.Database()) + feedsService = feeds.NewService( + feedsORM, + jobORM, + db, + jobSpawner, + keyStore, + cfg.Insecure(), + cfg.JobPipeline(), + cfg.OCR(), + cfg.OCR2(), + cfg.Database(), + legacyEVMChains, + globalLogger, + opts.Version, + ) + } else { + feedsService = &feeds.NullService{} } for _, s := range srvcs { diff --git a/core/services/chainlink/relayer_chain_interoperators.go b/core/services/chainlink/relayer_chain_interoperators.go index 1a0dbadd26..6513184d9e 100644 --- a/core/services/chainlink/relayer_chain_interoperators.go +++ b/core/services/chainlink/relayer_chain_interoperators.go @@ -90,9 +90,9 @@ func NewCoreRelayerChainInteroperators(initFuncs ...CoreRelayerChainInitFunc) (* srvs: make([]services.ServiceCtx, 0), } for _, initFn := range initFuncs { - err2 := initFn(cr) - if err2 != nil { - return nil, err2 + err := initFn(cr) + if err != nil { + return nil, err } } return cr, nil diff --git a/core/services/chainlink/relayer_chain_interoperators_test.go b/core/services/chainlink/relayer_chain_interoperators_test.go index 9cfe354fe9..527dacd56d 100644 --- a/core/services/chainlink/relayer_chain_interoperators_test.go +++ b/core/services/chainlink/relayer_chain_interoperators_test.go @@ -174,8 +174,6 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { factory := chainlink.RelayerFactory{ Logger: lggr, - DB: db, - QConfig: cfg.Database(), LoopRegistry: plugins.NewLoopRegistry(lggr), GRPCOpts: loop.GRPCOpts{}, } @@ -207,10 +205,11 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { {name: "2 evm chains with 3 nodes", initFuncs: []chainlink.CoreRelayerChainInitFunc{ chainlink.InitEVM(testctx, factory, chainlink.EVMFactoryConfig{ - RelayerConfig: &evm.RelayerConfig{ + ChainOpts: evm.ChainOpts{ AppConfig: cfg, EventBroadcaster: pg.NewNullEventBroadcaster(), MailMon: &utils.MailboxMonitor{}, + DB: db, }, CSAETHKeystore: keyStore, }), @@ -262,7 +261,9 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { chainlink.InitCosmos(testctx, factory, chainlink.CosmosFactoryConfig{ Keystore: keyStore.Cosmos(), CosmosConfigs: cfg.CosmosConfigs(), - EventBroadcaster: pg.NewNullEventBroadcaster()}), + EventBroadcaster: pg.NewNullEventBroadcaster(), + DB: db, + QConfig: cfg.Database()}), }, expectedCosmosChainCnt: 2, expectedCosmosNodeCnt: 2, @@ -279,10 +280,11 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { Keystore: keyStore.Solana(), SolanaConfigs: cfg.SolanaConfigs()}), chainlink.InitEVM(testctx, factory, chainlink.EVMFactoryConfig{ - RelayerConfig: &evm.RelayerConfig{ + ChainOpts: evm.ChainOpts{ AppConfig: cfg, EventBroadcaster: pg.NewNullEventBroadcaster(), MailMon: &utils.MailboxMonitor{}, + DB: db, }, CSAETHKeystore: keyStore, }), @@ -293,6 +295,8 @@ func TestCoreRelayerChainInteroperators(t *testing.T) { Keystore: keyStore.Cosmos(), CosmosConfigs: cfg.CosmosConfigs(), EventBroadcaster: pg.NewNullEventBroadcaster(), + DB: db, + QConfig: cfg.Database(), }), }, expectedEVMChainCnt: 2, diff --git a/core/services/chainlink/relayer_factory.go b/core/services/chainlink/relayer_factory.go index 0a0d653f5f..c0541f4384 100644 --- a/core/services/chainlink/relayer_factory.go +++ b/core/services/chainlink/relayer_factory.go @@ -2,9 +2,11 @@ package chainlink import ( "context" + "errors" "fmt" "github.com/pelletier/go-toml/v2" + "github.com/smartcontractkit/sqlx" pkgcosmos "github.com/smartcontractkit/chainlink-cosmos/pkg/cosmos" @@ -27,14 +29,12 @@ import ( type RelayerFactory struct { logger.Logger - *sqlx.DB - pg.QConfig *plugins.LoopRegistry loop.GRPCOpts } type EVMFactoryConfig struct { - *evm.RelayerConfig + evm.ChainOpts evmrelay.CSAETHKeystore } @@ -45,10 +45,9 @@ func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (m // 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.Named("EVM"), - DB: r.DB, - KeyStore: config.CSAETHKeystore.Eth(), - RelayerConfig: config.RelayerConfig, + Logger: r.Logger.Named("EVM"), + KeyStore: config.CSAETHKeystore.Eth(), + ChainOpts: config.ChainOpts, } evmRelayExtenders, err := evmrelay.NewChainRelayerExtenders(ctx, ccOpts) @@ -58,15 +57,28 @@ func (r *RelayerFactory) NewEVM(ctx context.Context, config EVMFactoryConfig) (m legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(evmRelayExtenders) for _, ext := range evmRelayExtenders.Slice() { relayID := relay.ID{Network: relay.EVM, ChainID: relay.ChainID(ext.Chain().ID().String())} - chain, err := legacyChains.Get(relayID.ChainID) - if err != nil { - return nil, err + chain, err2 := legacyChains.Get(relayID.ChainID) + if err2 != nil { + return nil, err2 + } + + relayerOpts := evmrelay.RelayerOpts{ + DB: ccOpts.DB, + QConfig: ccOpts.AppConfig.Database(), + CSAETHKeystore: config.CSAETHKeystore, + EventBroadcaster: ccOpts.EventBroadcaster, } - relayer := evmrelay.NewLoopRelayServerAdapter(evmrelay.NewRelayer(ccOpts.DB, chain, r.QConfig, ccOpts.Logger, config.CSAETHKeystore, ccOpts.EventBroadcaster), ext) - relayers[relayID] = relayer + relayer, err2 := evmrelay.NewRelayer(ccOpts.Logger, chain, relayerOpts) + if err2 != nil { + err = errors.Join(err, err2) + continue + } + + relayers[relayID] = evmrelay.NewLoopRelayServerAdapter(relayer, ext) } - return relayers, nil + // always return err because it is accumulating individual errors + return relayers, err } type SolanaFactoryConfig struct { @@ -209,9 +221,39 @@ type CosmosFactoryConfig struct { Keystore keystore.Cosmos cosmos.CosmosConfigs EventBroadcaster pg.EventBroadcaster + *sqlx.DB + pg.QConfig +} + +func (c CosmosFactoryConfig) Validate() error { + var err error + if c.Keystore == nil { + err = errors.Join(err, fmt.Errorf("nil Keystore")) + } + if len(c.CosmosConfigs) == 0 { + err = errors.Join(err, fmt.Errorf("no CosmosConfigs provided")) + } + if c.EventBroadcaster == nil { + err = errors.Join(err, fmt.Errorf("nil EventBroadcaster")) + } + if c.DB == nil { + err = errors.Join(err, fmt.Errorf("nil DB")) + } + if c.QConfig == nil { + err = errors.Join(err, fmt.Errorf("nil QConfig")) + } + + if err != nil { + err = fmt.Errorf("invalid CosmosFactoryConfig: %w", err) + } + return err } func (r *RelayerFactory) NewCosmos(ctx context.Context, config CosmosFactoryConfig) (map[relay.ID]cosmos.LoopRelayerChainer, error) { + err := config.Validate() + if err != nil { + return nil, fmt.Errorf("cannot create Cosmos relayer: %w", err) + } relayers := make(map[relay.ID]cosmos.LoopRelayerChainer) var ( @@ -224,9 +266,9 @@ func (r *RelayerFactory) NewCosmos(ctx context.Context, config CosmosFactoryConf relayId := relay.ID{Network: relay.Cosmos, ChainID: relay.ChainID(*chainCfg.ChainID)} opts := cosmos.ChainOpts{ - QueryConfig: r.QConfig, + QueryConfig: config.QConfig, Logger: lggr.Named(relayId.ChainID), - DB: r.DB, + DB: config.DB, KeyStore: loopKs, EventBroadcaster: config.EventBroadcaster, } diff --git a/core/services/cron/cron.go b/core/services/cron/cron.go index 56c67096e5..e89dd1ceab 100644 --- a/core/services/cron/cron.go +++ b/core/services/cron/cron.go @@ -79,7 +79,7 @@ func (cr *Cron) runPipeline() { run := pipeline.NewRun(*cr.jobSpec.PipelineSpec, vars) - _, err := cr.pipelineRunner.Run(ctx, &run, cr.logger, false, nil) + _, err := cr.pipelineRunner.Run(ctx, run, cr.logger, false, nil) if err != nil { cr.logger.Errorf("Error executing new run for jobSpec ID %v", cr.jobSpec.ID) } diff --git a/core/services/directrequest/delegate.go b/core/services/directrequest/delegate.go index f0ba5276ce..39564b8c8b 100644 --- a/core/services/directrequest/delegate.go +++ b/core/services/directrequest/delegate.go @@ -370,7 +370,7 @@ func (l *listener) handleOracleRequest(request *operator_wrapper.OperatorOracleR }, }) run := pipeline.NewRun(*l.job.PipelineSpec, vars) - _, err := l.pipelineRunner.Run(ctx, &run, l.logger, true, func(tx pg.Queryer) error { + _, err := l.pipelineRunner.Run(ctx, run, l.logger, true, func(tx pg.Queryer) error { l.markLogConsumed(lb, pg.WithQueryer(tx)) return nil }) diff --git a/core/services/feeds/service_test.go b/core/services/feeds/service_test.go index db6497d11f..85f14e407f 100644 --- a/core/services/feeds/service_test.go +++ b/core/services/feeds/service_test.go @@ -180,7 +180,7 @@ 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() - relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{GeneralConfig: gcfg, + relayExtenders := evmtest.NewChainRelayExtenders(t, evmtest.TestChainOpts{DB: db, GeneralConfig: gcfg, HeadTracker: headtracker.NullTracker, KeyStore: ethKeyStore}) legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) keyStore.On("Eth").Return(ethKeyStore) diff --git a/core/services/fluxmonitorv2/flux_monitor.go b/core/services/fluxmonitorv2/flux_monitor.go index 11e9b25be0..0b09655707 100644 --- a/core/services/fluxmonitorv2/flux_monitor.go +++ b/core/services/fluxmonitorv2/flux_monitor.go @@ -769,7 +769,7 @@ func (fm *FluxMonitor) respondToNewRoundLog(log flux_aggregator_wrapper.FluxAggr } err = fm.q.Transaction(func(tx pg.Queryer) error { - if err2 := fm.runner.InsertFinishedRun(&run, false, pg.WithQueryer(tx)); err2 != nil { + if err2 := fm.runner.InsertFinishedRun(run, false, pg.WithQueryer(tx)); err2 != nil { return err2 } if err2 := fm.queueTransactionForTxm(tx, run.ID, answer, roundState.RoundId, &log); err2 != nil { @@ -993,7 +993,7 @@ func (fm *FluxMonitor) pollIfEligible(pollReq PollRequestType, deviationChecker } err = fm.q.Transaction(func(tx pg.Queryer) error { - if err2 := fm.runner.InsertFinishedRun(&run, true, pg.WithQueryer(tx)); err2 != nil { + if err2 := fm.runner.InsertFinishedRun(run, true, pg.WithQueryer(tx)); err2 != nil { return err2 } if err2 := fm.queueTransactionForTxm(tx, run.ID, answer, roundState.RoundId, nil); err2 != nil { diff --git a/core/services/fluxmonitorv2/flux_monitor_test.go b/core/services/fluxmonitorv2/flux_monitor_test.go index e165ce6820..27d40cd69c 100644 --- a/core/services/fluxmonitorv2/flux_monitor_test.go +++ b/core/services/fluxmonitorv2/flux_monitor_test.go @@ -455,7 +455,7 @@ func TestFluxMonitor_PollIfEligible(t *testing.T) { }, }, ), mock.Anything). - Return(run, pipeline.TaskRunResults{ + Return(&run, pipeline.TaskRunResults{ { Result: pipeline.Result{ Value: decimal.NewFromInt(answers.polledAnswer), @@ -584,7 +584,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) { tm.orm.On("MostRecentFluxMonitorRoundID", contractAddress).Return(uint32(4), nil) // Round 1 - run := pipeline.Run{ID: 1} + run := &pipeline.Run{ID: 1} tm.orm. On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(1), mock.Anything). Return(fluxmonitorv2.FluxMonitorRoundStatsV2{ @@ -624,7 +624,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) { Return(nil).Once() // Round 3 - run = pipeline.Run{ID: 2} + run = &pipeline.Run{ID: 2} tm.orm. On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(3), mock.Anything). Return(fluxmonitorv2.FluxMonitorRoundStatsV2{ @@ -663,7 +663,7 @@ func TestPollingDeviationChecker_BuffersLogs(t *testing.T) { Return(nil).Once() // Round 4 - run = pipeline.Run{ID: 3} + run = &pipeline.Run{ID: 3} tm.orm. On("FindOrCreateFluxMonitorRoundStats", contractAddress, uint32(4), mock.Anything). Return(fluxmonitorv2.FluxMonitorRoundStatsV2{ @@ -1484,7 +1484,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) { answer = 100 ) - run := pipeline.Run{ID: 1} + run := &pipeline.Run{ID: 1} tm.keyStore.On("EnabledKeysForChain", testutils.FixtureChainID).Return([]ethkey.KeyV2{{Address: nodeAddr}}, nil).Once() tm.logBroadcaster.On("IsConnected").Return(true).Maybe() @@ -1600,7 +1600,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) { answer = 100 ) - run := pipeline.Run{ID: 1} + run := &pipeline.Run{ID: 1} tm.keyStore.On("EnabledKeysForChain", testutils.FixtureChainID).Return([]ethkey.KeyV2{{Address: nodeAddr}}, nil).Once() tm.logBroadcaster.On("IsConnected").Return(true).Maybe() @@ -1696,7 +1696,7 @@ func TestFluxMonitor_DoesNotDoubleSubmit(t *testing.T) { roundID = 3 answer = 100 ) - run := pipeline.Run{ID: 1} + run := &pipeline.Run{ID: 1} tm.keyStore.On("EnabledKeysForChain", testutils.FixtureChainID).Return([]ethkey.KeyV2{{Address: nodeAddr}}, nil).Once() tm.logBroadcaster.On("IsConnected").Return(true).Maybe() @@ -1901,7 +1901,7 @@ func TestFluxMonitor_DrumbeatTicker(t *testing.T) { }, }, ), mock.Anything). - Return(pipeline.Run{ID: runID}, pipeline.TaskRunResults{ + Return(&pipeline.Run{ID: runID}, pipeline.TaskRunResults{ { Result: pipeline.Result{ Value: decimal.NewFromInt(fetchedAnswer), diff --git a/core/services/functions/listener.go b/core/services/functions/listener.go index d9272aca3a..084d1530a7 100644 --- a/core/services/functions/listener.go +++ b/core/services/functions/listener.go @@ -724,7 +724,7 @@ func (l *FunctionsListener) getSecrets(ctx context.Context, eaClient ExternalAda Version: donSecrets.Version, }) if err != nil { - return "", errors.Wrap(err, "failed to fetch S4 record for a secret"), nil + return "", errors.Wrap(err, "failed to fetch DONHosted secrets"), nil } secrets = record.Payload } diff --git a/core/services/gateway/common/utils.go b/core/services/gateway/common/utils.go index 7501504f87..2e5033432b 100644 --- a/core/services/gateway/common/utils.go +++ b/core/services/gateway/common/utils.go @@ -28,6 +28,9 @@ func StringToAlignedBytes(input string, size int) []byte { func AlignedBytesToString(data []byte) string { idx := slices.IndexFunc(data, func(b byte) bool { return b == 0 }) + if idx == -1 { + return string(data) + } return string(data[:idx]) } diff --git a/core/services/gateway/common/utils_test.go b/core/services/gateway/common/utils_test.go index e223ba1e9f..f3ed6a0dfb 100644 --- a/core/services/gateway/common/utils_test.go +++ b/core/services/gateway/common/utils_test.go @@ -26,6 +26,10 @@ func TestUtils_StringAlignedBytesConversions(t *testing.T) { data := common.StringToAlignedBytes(val, 40) require.Equal(t, val, common.AlignedBytesToString(data)) + val = "0123456789" + data = common.StringToAlignedBytes(val, 10) + require.Equal(t, val, common.AlignedBytesToString(data)) + val = "世界" data = common.StringToAlignedBytes(val, 40) require.Equal(t, val, common.AlignedBytesToString(data)) diff --git a/core/services/gateway/connector/connector.go b/core/services/gateway/connector/connector.go index be544a6d94..4cc84d3749 100644 --- a/core/services/gateway/connector/connector.go +++ b/core/services/gateway/connector/connector.go @@ -79,7 +79,7 @@ type gatewayState struct { } func NewGatewayConnector(config *ConnectorConfig, signer Signer, handler GatewayConnectorHandler, clock utils.Clock, lggr logger.Logger) (GatewayConnector, error) { - if signer == nil || handler == nil || clock == nil { + if config == nil || signer == nil || handler == nil || clock == nil || lggr == nil { return nil, errors.New("nil dependency") } if len(config.DonId) == 0 || len(config.DonId) > int(network.HandshakeDonIdLen) { diff --git a/core/services/gateway/gateway.go b/core/services/gateway/gateway.go index b97bed71ee..fb38ae10de 100644 --- a/core/services/gateway/gateway.go +++ b/core/services/gateway/gateway.go @@ -132,6 +132,9 @@ func (g *gateway) ProcessRequest(ctx context.Context, rawRequest []byte) (rawRes if err != nil { return newError(g.codec, "", api.UserMessageParseError, err.Error()) } + if msg == nil { + return newError(g.codec, "", api.UserMessageParseError, "nil message") + } if err = msg.Validate(); err != nil { return newError(g.codec, msg.Body.MessageId, api.UserMessageParseError, err.Error()) } diff --git a/core/services/gateway/handlers/functions/allowlist.go b/core/services/gateway/handlers/functions/allowlist.go index 19bc61aaba..0ee9b5bcfb 100644 --- a/core/services/gateway/handlers/functions/allowlist.go +++ b/core/services/gateway/handlers/functions/allowlist.go @@ -2,6 +2,7 @@ package functions import ( "context" + "encoding/hex" "fmt" "math/big" "sync" @@ -177,7 +178,7 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b if err != nil { return errors.Wrap(err, "unexpected error during functions_router.GetAllowListId") } - a.lggr.Debugw("successfully fetched allowlist route ID", "id", tosID) + a.lggr.Debugw("successfully fetched allowlist route ID", "id", hex.EncodeToString(tosID[:])) if tosID == [32]byte{} { return errors.New("allowlist route ID has not been set") } diff --git a/core/services/gateway/handlers/functions/handler.functions.go b/core/services/gateway/handlers/functions/handler.functions.go index 82d4976db2..7eb15ef6ff 100644 --- a/core/services/gateway/handlers/functions/handler.functions.go +++ b/core/services/gateway/handlers/functions/handler.functions.go @@ -230,10 +230,10 @@ func (h *functionsHandler) processSecretsResponse(response *api.Message, respons if _, exists := responseData.responses[response.Body.Sender]; exists { return nil, nil, errors.New("duplicate response") } - responseData.responses[response.Body.Sender] = response if response.Body.Method != responseData.request.Body.Method { return nil, responseData, errors.New("invalid method") } + responseData.responses[response.Body.Sender] = response var responsePayload SecretsResponseBase err := json.Unmarshal(response.Body.Payload, &responsePayload) if err != nil { diff --git a/core/services/gateway/network/httpserver.go b/core/services/gateway/network/httpserver.go index 26b9126da3..d9d3e5ee7e 100644 --- a/core/services/gateway/network/httpserver.go +++ b/core/services/gateway/network/httpserver.go @@ -54,6 +54,11 @@ type httpServer struct { lggr logger.Logger } +const ( + HealthCheckPath = "/health" + HealthCheckResponse = "OK" +) + func NewHttpServer(config *HTTPServerConfig, lggr logger.Logger) HttpServer { baseCtx, cancelBaseCtx := context.WithCancel(context.Background()) server := &httpServer{ @@ -64,6 +69,7 @@ func NewHttpServer(config *HTTPServerConfig, lggr logger.Logger) HttpServer { } mux := http.NewServeMux() mux.Handle(config.Path, http.HandlerFunc(server.handleRequest)) + mux.Handle(HealthCheckPath, http.HandlerFunc(server.handleHealthCheck)) server.server = &http.Server{ Addr: fmt.Sprintf("%s:%d", config.Host, config.Port), Handler: mux, @@ -75,6 +81,14 @@ func NewHttpServer(config *HTTPServerConfig, lggr logger.Logger) HttpServer { return server } +func (s *httpServer) handleHealthCheck(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _, err := w.Write([]byte(HealthCheckResponse)) + if err != nil { + s.lggr.Debug("error when writing response for healthcheck", err) + } +} + func (s *httpServer) handleRequest(w http.ResponseWriter, r *http.Request) { source := http.MaxBytesReader(nil, r.Body, s.config.MaxRequestBytes) rawMessage, err := io.ReadAll(source) diff --git a/core/services/gateway/network/httpserver_test.go b/core/services/gateway/network/httpserver_test.go index 2e20957cf3..92215245e2 100644 --- a/core/services/gateway/network/httpserver_test.go +++ b/core/services/gateway/network/httpserver_test.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "net/http" + "strings" "testing" "github.com/stretchr/testify/mock" @@ -74,3 +75,15 @@ func TestHTTPServer_HandleRequest_RequestBodyTooBig(t *testing.T) { resp := sendRequest(t, url, []byte("0123456789")) require.Equal(t, http.StatusBadRequest, resp.StatusCode) } + +func TestHTTPServer_HandleHealthCheck(t *testing.T) { + server, _, url := startNewServer(t, 100_000, 100_000) + defer server.Close() + + url = strings.Replace(url, HTTPTestPath, network.HealthCheckPath, 1) + resp := sendRequest(t, url, []byte{}) + respBytes, err := io.ReadAll(resp.Body) + require.NoError(t, err) + require.Equal(t, http.StatusOK, resp.StatusCode) + require.Equal(t, []byte(network.HealthCheckResponse), respBytes) +} diff --git a/core/services/gateway/network/wsclient.go b/core/services/gateway/network/wsclient.go index 04b6fe3f33..bc248d202a 100644 --- a/core/services/gateway/network/wsclient.go +++ b/core/services/gateway/network/wsclient.go @@ -57,6 +57,11 @@ func (c *webSocketClient) Connect(ctx context.Context, url *url.URL) (*websocket } challengeStr := resp.Header.Get(WsServerHandshakeChallengeHeaderName) + if challengeStr == "" { + c.lggr.Error("WebSocketClient: empty challenge") + c.tryCloseConn(conn) + return nil, err + } challenge, err := base64.StdEncoding.DecodeString(challengeStr) if err != nil { c.lggr.Errorf("WebSocketClient: couldn't decode challenge: %s: %v", challengeStr, err) diff --git a/core/services/job/job_orm_test.go b/core/services/job/job_orm_test.go index b885bf4f83..673d4f1e0f 100644 --- a/core/services/job/job_orm_test.go +++ b/core/services/job/job_orm_test.go @@ -10,7 +10,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" "github.com/lib/pq" - "github.com/pelletier/go-toml" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gopkg.in/guregu/null.v4" @@ -217,9 +216,23 @@ func TestORM(t *testing.T) { }) t.Run("creates a job with a direct request spec", func(t *testing.T) { - tree, err := toml.LoadFile("../../testdata/tomlspecs/direct-request-spec.toml") - require.NoError(t, err) - jb, err := directrequest.ValidatedDirectRequestSpec(tree.String()) + drSpec := fmt.Sprintf(` + type = "directrequest" + schemaVersion = 1 + evmChainID = "0" + name = "example eth request event spec" + contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C" + externalJobID = "%s" + observationSource = """ + ds1 [type=http method=GET url="http://example.com" allowunrestrictednetworkaccess="true"]; + ds1_merge [type=merge left="{}"] + ds1_parse [type=jsonparse path="USD"]; + ds1_multiply [type=multiply times=100]; + ds1 -> ds1_parse -> ds1_multiply; + """ + `, uuid.New()) + + jb, err := directrequest.ValidatedDirectRequestSpec(drSpec) require.NoError(t, err) err = orm.CreateJob(&jb) require.NoError(t, err) @@ -260,6 +273,7 @@ func TestORM(t *testing.T) { 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.HeartbeatPeriod, savedJob.BlockhashStoreSpec.HeartbeatPeriod) 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) diff --git a/core/services/job/models.go b/core/services/job/models.go index 03015aa1a7..5787ce5fb5 100644 --- a/core/services/job/models.go +++ b/core/services/job/models.go @@ -573,6 +573,12 @@ type BlockhashStoreSpec struct { // WaitBlocks defines the minimum age of blocks whose hashes should be stored. WaitBlocks int32 `toml:"waitBlocks"` + // HeartbeatPeriodTime defines the number of seconds by which we "heartbeat store" + // a blockhash into the blockhash store contract. + // This is so that we always have a blockhash to anchor to in the event we need to do a + // backwards mode on the contract. + HeartbeatPeriod time.Duration `toml:"heartbeatPeriod"` + // BlockhashStoreAddress is the address of the BlockhashStore contract to store blockhashes // into. BlockhashStoreAddress ethkey.EIP55Address `toml:"blockhashStoreAddress"` diff --git a/core/services/job/orm.go b/core/services/job/orm.go index 190df2f496..369ce039ad 100644 --- a/core/services/job/orm.go +++ b/core/services/job/orm.go @@ -388,8 +388,8 @@ func (o *orm) CreateJob(jb *Job, qopts ...pg.QOpt) error { return errors.New("evm chain id must be defined") } var specID int32 - 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()) + 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, heartbeat_period, 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, :heartbeat_period, :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") diff --git a/core/services/job/spawner_test.go b/core/services/job/spawner_test.go index 631f7ebfee..7dbf811f78 100644 --- a/core/services/job/spawner_test.go +++ b/core/services/job/spawner_test.go @@ -284,7 +284,14 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { legacyChains := evmrelay.NewLegacyChainsFromRelayerExtenders(relayExtenders) chain := evmtest.MustGetDefaultChain(t, legacyChains) - evmRelayer := evmrelayer.NewRelayer(testopts.DB, chain, testopts.GeneralConfig.Database(), lggr, keyStore, pg.NewNullEventBroadcaster()) + evmRelayer, err := evmrelayer.NewRelayer(lggr, chain, evmrelayer.RelayerOpts{ + DB: db, + QConfig: testopts.GeneralConfig.Database(), + CSAETHKeystore: keyStore, + EventBroadcaster: pg.NewNullEventBroadcaster(), + }) + assert.NoError(t, err) + testRelayGetter := &relayGetter{ e: relayExtenders.Slice()[0], r: evmRelayer, @@ -306,7 +313,7 @@ func TestSpawner_CreateJobDeleteJob(t *testing.T) { 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/keeper/upkeep_executer.go b/core/services/keeper/upkeep_executer.go index 249d321746..435b245792 100644 --- a/core/services/keeper/upkeep_executer.go +++ b/core/services/keeper/upkeep_executer.go @@ -223,7 +223,7 @@ func (ex *UpkeepExecuter) execute(upkeep UpkeepRegistration, head *evmtypes.Head ex.job.PipelineSpec.DotDagSource = pipeline.KeepersObservationSource run := pipeline.NewRun(*ex.job.PipelineSpec, vars) - if _, err := ex.pr.Run(ctxService, &run, svcLogger, true, nil); err != nil { + if _, err := ex.pr.Run(ctxService, run, svcLogger, true, nil); err != nil { svcLogger.Error(errors.Wrap(err, "failed executing run")) return } diff --git a/core/services/metatx/integration_test.go b/core/services/metatx/integration_test.go index 92600df470..748b2fe048 100644 --- a/core/services/metatx/integration_test.go +++ b/core/services/metatx/integration_test.go @@ -26,7 +26,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ethkey" "github.com/smartcontractkit/chainlink/v2/core/services/metatx" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/integration" ) @@ -235,7 +234,7 @@ merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_p executionLogs := ccipContracts.AllNodesHaveExecutedSeqNums(t, geCurrentSeqNum, geCurrentSeqNum) assert.Len(t, executionLogs, 1) - ccipContracts.AssertExecState(t, executionLogs[0], abihelpers.ExecutionStateSuccess) + ccipContracts.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) // source token is locked in the token pool lockedTokenBal, err := sourceToken.BalanceOf(nil, sourcePoolAddress) diff --git a/core/services/ocr/delegate.go b/core/services/ocr/delegate.go index 9cb736a58f..9ed22d01e7 100644 --- a/core/services/ocr/delegate.go +++ b/core/services/ocr/delegate.go @@ -274,7 +274,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) (services []job effectiveTransmitterAddress, ) - runResults := make(chan pipeline.Run, chain.Config().JobPipeline().ResultWriteQueueDepth()) + runResults := make(chan *pipeline.Run, chain.Config().JobPipeline().ResultWriteQueueDepth()) var configOverrider ocrtypes.ConfigOverrider configOverriderService, err := d.maybeCreateConfigOverrider(lggr, chain, concreteSpec.ContractAddress) diff --git a/core/services/ocr2/delegate.go b/core/services/ocr2/delegate.go index 966014b239..e8c50610b3 100644 --- a/core/services/ocr2/delegate.go +++ b/core/services/ocr2/delegate.go @@ -287,13 +287,13 @@ func (d *Delegate) cleanupEVM(jb job.Job, q pg.Queryer, relayID relay.ID) error d.lggr.Errorw("failed to derive ocr2keeper filter names from spec", "err", err, "spec", spec) } case types.CCIPCommit: - err = ccip.UnregisterCommitPluginLpFilters(context.Background(), spec, d.legacyChains, pg.WithQueryer(q)) + err = ccip.UnregisterCommitPluginLpFilters(context.Background(), d.lggr, jb, d.pipelineRunner, d.legacyChains, pg.WithQueryer(q)) if err != nil { d.lggr.Errorw("failed to unregister ccip commit plugin filters", "err", err, "spec", spec) } return nil case types.CCIPExecution: - err = ccip.UnregisterExecPluginLpFilters(context.Background(), d.lggr, spec, d.legacyChains, pg.WithQueryer(q)) + err = ccip.UnregisterExecPluginLpFilters(context.Background(), d.lggr, jb, d.legacyChains, pg.WithQueryer(q)) if err != nil { d.lggr.Errorw("failed to unregister ccip exec plugin filters", "err", err, "spec", spec) } @@ -304,7 +304,7 @@ func (d *Delegate) cleanupEVM(jb job.Job, q pg.Queryer, relayID relay.ID) error rargs := types.RelayArgs{ ExternalJobID: jb.ExternalJobID, - JobID: spec.ID, + JobID: jb.ID, ContractID: spec.ContractID, New: false, RelayConfig: spec.RelayConfig.Bytes(), @@ -415,7 +415,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC spec.CaptureEATelemetry = d.cfg.OCR2().CaptureEATelemetry() - runResults := make(chan pipeline.Run, d.cfg.JobPipeline().ResultWriteQueueDepth()) + runResults := make(chan *pipeline.Run, d.cfg.JobPipeline().ResultWriteQueueDepth()) ctx := lggrCtx.ContextWithValues(context.Background()) switch spec.PluginType { @@ -496,7 +496,7 @@ func (d *Delegate) newServicesMercury( ctx context.Context, lggr logger.SugaredLogger, jb job.Job, - runResults chan pipeline.Run, + runResults chan *pipeline.Run, bootstrapPeers []commontypes.BootstrapperLocator, kb ocr2key.KeyBundle, ocrDB *db, @@ -534,7 +534,7 @@ func (d *Delegate) newServicesMercury( provider, err2 := relayer.NewPluginProvider(ctx, types.RelayArgs{ ExternalJobID: jb.ExternalJobID, - JobID: spec.ID, + JobID: jb.ID, ContractID: spec.ContractID, New: d.isNewlyCreatedJob, RelayConfig: spec.RelayConfig.Bytes(), @@ -582,7 +582,7 @@ func (d *Delegate) newServicesMedian( ctx context.Context, lggr logger.SugaredLogger, jb job.Job, - runResults chan pipeline.Run, + runResults chan *pipeline.Run, bootstrapPeers []commontypes.BootstrapperLocator, kb ocr2key.KeyBundle, ocrDB *db, @@ -649,7 +649,7 @@ func (d *Delegate) newServicesDKG( dkgProvider, err2 := ocr2vrfRelayer.NewDKGProvider( types.RelayArgs{ ExternalJobID: jb.ExternalJobID, - JobID: spec.ID, + JobID: jb.ID, ContractID: spec.ContractID, New: d.isNewlyCreatedJob, RelayConfig: spec.RelayConfig.Bytes(), @@ -694,7 +694,7 @@ func (d *Delegate) newServicesDKG( func (d *Delegate) newServicesOCR2VRF( lggr logger.SugaredLogger, jb job.Job, - runResults chan pipeline.Run, + runResults chan *pipeline.Run, bootstrapPeers []commontypes.BootstrapperLocator, kb ocr2key.KeyBundle, ocrDB *db, @@ -734,7 +734,7 @@ func (d *Delegate) newServicesOCR2VRF( vrfProvider, err2 := ocr2vrfRelayer.NewOCR2VRFProvider( types.RelayArgs{ ExternalJobID: jb.ExternalJobID, - JobID: spec.ID, + JobID: jb.ID, ContractID: spec.ContractID, New: d.isNewlyCreatedJob, RelayConfig: spec.RelayConfig.Bytes(), @@ -749,7 +749,7 @@ func (d *Delegate) newServicesOCR2VRF( dkgProvider, err2 := ocr2vrfRelayer.NewDKGProvider( types.RelayArgs{ ExternalJobID: jb.ExternalJobID, - JobID: spec.ID, + JobID: jb.ID, ContractID: cfg.DKGContractAddress, RelayConfig: spec.RelayConfig.Bytes(), }, types.PluginArgs{ @@ -882,7 +882,7 @@ func (d *Delegate) newServicesOCR2VRF( func (d *Delegate) newServicesOCR2Keepers( lggr logger.SugaredLogger, jb job.Job, - runResults chan pipeline.Run, + runResults chan *pipeline.Run, bootstrapPeers []commontypes.BootstrapperLocator, kb ocr2key.KeyBundle, ocrDB *db, @@ -912,7 +912,7 @@ func (d *Delegate) newServicesOCR2Keepers( func (d *Delegate) newServicesOCR2Keepers21( lggr logger.SugaredLogger, jb job.Job, - runResults chan pipeline.Run, + runResults chan *pipeline.Run, bootstrapPeers []commontypes.BootstrapperLocator, kb ocr2key.KeyBundle, ocrDB *db, @@ -1031,7 +1031,7 @@ func (d *Delegate) newServicesOCR2Keepers21( func (d *Delegate) newServicesOCR2Keepers20( lggr logger.SugaredLogger, jb job.Job, - runResults chan pipeline.Run, + runResults chan *pipeline.Run, bootstrapPeers []commontypes.BootstrapperLocator, kb ocr2key.KeyBundle, ocrDB *db, @@ -1165,7 +1165,7 @@ func (d *Delegate) newServicesOCR2Keepers20( func (d *Delegate) newServicesOCR2Functions( lggr logger.SugaredLogger, jb job.Job, - runResults chan pipeline.Run, + runResults chan *pipeline.Run, bootstrapPeers []commontypes.BootstrapperLocator, kb ocr2key.KeyBundle, functionsOcrDB *db, @@ -1192,7 +1192,7 @@ func (d *Delegate) newServicesOCR2Functions( chain, types.RelayArgs{ ExternalJobID: jb.ExternalJobID, - JobID: spec.ID, + JobID: jb.ID, ContractID: spec.ContractID, RelayConfig: spec.RelayConfig.Bytes(), New: d.isNewlyCreatedJob, diff --git a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go index 1ed681f271..c80876ddd9 100644 --- a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go +++ b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers.go @@ -10,59 +10,11 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" - "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/utils" ) -// MessageExecutionState defines the execution states of CCIP messages. -type MessageExecutionState uint8 - -const ( - ExecutionStateUntouched MessageExecutionState = iota - ExecutionStateInProgress - ExecutionStateSuccess - ExecutionStateFailure -) - -var EventSignatures struct { - // OnRamp - SendRequested common.Hash - // CommitStore - ReportAccepted common.Hash - // OffRamp - ExecutionStateChanged common.Hash - PoolAdded common.Hash - PoolRemoved common.Hash - - // PriceRegistry - UsdPerUnitGasUpdated common.Hash - UsdPerTokenUpdated common.Hash - FeeTokenAdded common.Hash - FeeTokenRemoved common.Hash - - USDCMessageSent common.Hash - - // offset || sourceChainID || seqNum || ... - SendRequestedSequenceNumberWord int - // offset || priceUpdatesOffset || minSeqNum || maxSeqNum || merkleRoot - ReportAcceptedMaxSequenceNumberWord int - // sig || seqNum || messageId || ... - ExecutionStateChangedSequenceNumberIndex int -} - -var ( - MessageArgs abi.Arguments - TokenAmountsArgs abi.Arguments - CommitReportArgs abi.Arguments - ExecutionReportArgs abi.Arguments -) - -func getIDOrPanic(name string, abi2 abi.ABI) common.Hash { +func MustGetEventID(name string, abi2 abi.ABI) common.Hash { event, ok := abi2.Events[name] if !ok { panic(fmt.Sprintf("missing event %s", name)) @@ -70,158 +22,28 @@ func getIDOrPanic(name string, abi2 abi.ABI) common.Hash { return event.ID } -func getTupleNamedElem(name string, arg abi.Argument) *abi.Type { - if arg.Type.T != abi.TupleTy { - return nil - } - for i, elem := range arg.Type.TupleElems { - if arg.Type.TupleRawNames[i] == name { - return elem - } - } - return nil -} - -func init() { - onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp.EVM2EVMOnRampABI)) - if err != nil { - panic(err) - } - EventSignatures.SendRequested = getIDOrPanic("CCIPSendRequested", onRampABI) - EventSignatures.SendRequestedSequenceNumberWord = 4 - - commitStoreABI, err := abi.JSON(strings.NewReader(commit_store.CommitStoreABI)) - if err != nil { - panic(err) - } - EventSignatures.ReportAccepted = getIDOrPanic("ReportAccepted", commitStoreABI) - EventSignatures.ReportAcceptedMaxSequenceNumberWord = 3 - - offRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_offramp.EVM2EVMOffRampABI)) - if err != nil { - panic(err) - } - EventSignatures.ExecutionStateChanged = getIDOrPanic("ExecutionStateChanged", offRampABI) - EventSignatures.ExecutionStateChangedSequenceNumberIndex = 1 - EventSignatures.PoolAdded = getIDOrPanic("PoolAdded", offRampABI) - EventSignatures.PoolRemoved = getIDOrPanic("PoolRemoved", offRampABI) - - priceRegistryABI, err := abi.JSON(strings.NewReader(price_registry.PriceRegistryABI)) - if err != nil { - panic(err) - } - EventSignatures.UsdPerUnitGasUpdated = getIDOrPanic("UsdPerUnitGasUpdated", priceRegistryABI) - EventSignatures.UsdPerTokenUpdated = getIDOrPanic("UsdPerTokenUpdated", priceRegistryABI) - EventSignatures.FeeTokenAdded = getIDOrPanic("FeeTokenAdded", priceRegistryABI) - EventSignatures.FeeTokenRemoved = getIDOrPanic("FeeTokenRemoved", priceRegistryABI) - - // arguments - MessageArgs = onRampABI.Events["CCIPSendRequested"].Inputs - tokenAmountsTy := getTupleNamedElem("tokenAmounts", MessageArgs[0]) - if tokenAmountsTy == nil { - panic(fmt.Sprintf("missing component '%s' in tuple %+v", "tokenAmounts", MessageArgs)) - } - TokenAmountsArgs = abi.Arguments{{Type: *tokenAmountsTy, Name: "tokenAmounts"}} - - CommitReportArgs = commitStoreABI.Events["ReportAccepted"].Inputs - - manuallyExecuteMethod, ok := offRampABI.Methods["manuallyExecute"] +func MustGetEventInputs(name string, abi2 abi.ABI) abi.Arguments { + m, ok := abi2.Events[name] if !ok { - panic("missing event 'manuallyExecute'") - } - ExecutionReportArgs = manuallyExecuteMethod.Inputs[:1] - - EventSignatures.USDCMessageSent = utils.Keccak256Fixed([]byte("MessageSent(bytes)")) -} - -func MessagesFromExecutionReport(report types.Report) ([]evm_2_evm_offramp.InternalEVM2EVMMessage, error) { - decodedExecutionReport, err := DecodeExecutionReport(report) - if err != nil { - return nil, err + panic(fmt.Sprintf("missing event %s", name)) } - return decodedExecutionReport.Messages, nil + return m.Inputs } -func DecodeOffRampMessage(b []byte) (*evm_2_evm_offramp.InternalEVM2EVMMessage, error) { - unpacked, err := MessageArgs.Unpack(b) - if err != nil { - return nil, err - } - if len(unpacked) == 0 { - return nil, fmt.Errorf("no message found when unpacking") - } - - // Note must use unnamed type here - receivedCp, ok := unpacked[0].(struct { - SourceChainSelector uint64 `json:"sourceChainSelector"` - Sender common.Address `json:"sender"` - Receiver common.Address `json:"receiver"` - SequenceNumber uint64 `json:"sequenceNumber"` - GasLimit *big.Int `json:"gasLimit"` - Strict bool `json:"strict"` - Nonce uint64 `json:"nonce"` - FeeToken common.Address `json:"feeToken"` - FeeTokenAmount *big.Int `json:"feeTokenAmount"` - Data []uint8 `json:"data"` - TokenAmounts []struct { - Token common.Address `json:"token"` - Amount *big.Int `json:"amount"` - } `json:"tokenAmounts"` - SourceTokenData [][]byte `json:"sourceTokenData"` - MessageId [32]byte `json:"messageId"` - }) +func MustGetMethodInputs(name string, abi2 abi.ABI) abi.Arguments { + m, ok := abi2.Methods[name] if !ok { - return nil, fmt.Errorf("invalid format have %T want %T", unpacked[0], receivedCp) + panic(fmt.Sprintf("missing method %s", name)) } - var tokensAndAmounts []evm_2_evm_offramp.ClientEVMTokenAmount - for _, tokenAndAmount := range receivedCp.TokenAmounts { - tokensAndAmounts = append(tokensAndAmounts, evm_2_evm_offramp.ClientEVMTokenAmount{ - Token: tokenAndAmount.Token, - Amount: tokenAndAmount.Amount, - }) - } - - return &evm_2_evm_offramp.InternalEVM2EVMMessage{ - SourceChainSelector: receivedCp.SourceChainSelector, - Sender: receivedCp.Sender, - Receiver: receivedCp.Receiver, - SequenceNumber: receivedCp.SequenceNumber, - GasLimit: receivedCp.GasLimit, - Strict: receivedCp.Strict, - Nonce: receivedCp.Nonce, - FeeToken: receivedCp.FeeToken, - FeeTokenAmount: receivedCp.FeeTokenAmount, - Data: receivedCp.Data, - TokenAmounts: tokensAndAmounts, - SourceTokenData: receivedCp.SourceTokenData, - MessageId: receivedCp.MessageId, - }, nil + return m.Inputs } -func OnRampMessageToOffRampMessage(msg evm_2_evm_onramp.InternalEVM2EVMMessage) evm_2_evm_offramp.InternalEVM2EVMMessage { - tokensAndAmounts := make([]evm_2_evm_offramp.ClientEVMTokenAmount, len(msg.TokenAmounts)) - for i, tokenAndAmount := range msg.TokenAmounts { - tokensAndAmounts[i] = evm_2_evm_offramp.ClientEVMTokenAmount{ - Token: tokenAndAmount.Token, - Amount: tokenAndAmount.Amount, - } - } - - return evm_2_evm_offramp.InternalEVM2EVMMessage{ - SourceChainSelector: msg.SourceChainSelector, - Sender: msg.Sender, - Receiver: msg.Receiver, - SequenceNumber: msg.SequenceNumber, - GasLimit: msg.GasLimit, - Strict: msg.Strict, - Nonce: msg.Nonce, - FeeToken: msg.FeeToken, - FeeTokenAmount: msg.FeeTokenAmount, - Data: msg.Data, - TokenAmounts: tokensAndAmounts, - SourceTokenData: msg.SourceTokenData, - MessageId: msg.MessageId, +func MustParseABI(abiStr string) abi.ABI { + abiParsed, err := abi.JSON(strings.NewReader(abiStr)) + if err != nil { + panic(err) } + return abiParsed } // ProofFlagsToBits transforms a list of boolean proof flags to a *big.Int @@ -236,138 +58,6 @@ func ProofFlagsToBits(proofFlags []bool) *big.Int { return encodedFlags } -func EncodeExecutionReport(execReport evm_2_evm_offramp.InternalExecutionReport) ([]byte, error) { - return ExecutionReportArgs.PackValues([]interface{}{&execReport}) -} - -func DecodeExecutionReport(report []byte) (evm_2_evm_offramp.InternalExecutionReport, error) { - unpacked, err := ExecutionReportArgs.Unpack(report) - if err != nil { - return evm_2_evm_offramp.InternalExecutionReport{}, err - } - if len(unpacked) == 0 { - return evm_2_evm_offramp.InternalExecutionReport{}, errors.New("assumptionViolation: expected at least one element") - } - - // Must be anonymous struct here - erStruct, ok := unpacked[0].(struct { - Messages []struct { - SourceChainSelector uint64 `json:"sourceChainSelector"` - Sender common.Address `json:"sender"` - Receiver common.Address `json:"receiver"` - SequenceNumber uint64 `json:"sequenceNumber"` - GasLimit *big.Int `json:"gasLimit"` - Strict bool `json:"strict"` - Nonce uint64 `json:"nonce"` - FeeToken common.Address `json:"feeToken"` - FeeTokenAmount *big.Int `json:"feeTokenAmount"` - Data []uint8 `json:"data"` - TokenAmounts []struct { - Token common.Address `json:"token"` - Amount *big.Int `json:"amount"` - } `json:"tokenAmounts"` - SourceTokenData [][]byte `json:"sourceTokenData"` - MessageId [32]byte `json:"messageId"` - } `json:"messages"` - OffchainTokenData [][][]byte `json:"offchainTokenData"` - Proofs [][32]uint8 `json:"proofs"` - ProofFlagBits *big.Int `json:"proofFlagBits"` - }) - if !ok { - return evm_2_evm_offramp.InternalExecutionReport{}, fmt.Errorf("got %T", unpacked[0]) - } - var er evm_2_evm_offramp.InternalExecutionReport - er.Messages = []evm_2_evm_offramp.InternalEVM2EVMMessage{} - - for _, msg := range erStruct.Messages { - var tokensAndAmounts []evm_2_evm_offramp.ClientEVMTokenAmount - for _, tokenAndAmount := range msg.TokenAmounts { - tokensAndAmounts = append(tokensAndAmounts, evm_2_evm_offramp.ClientEVMTokenAmount{ - Token: tokenAndAmount.Token, - Amount: tokenAndAmount.Amount, - }) - } - er.Messages = append(er.Messages, evm_2_evm_offramp.InternalEVM2EVMMessage{ - SourceChainSelector: msg.SourceChainSelector, - SequenceNumber: msg.SequenceNumber, - FeeTokenAmount: msg.FeeTokenAmount, - Sender: msg.Sender, - Nonce: msg.Nonce, - GasLimit: msg.GasLimit, - Strict: msg.Strict, - Receiver: msg.Receiver, - Data: msg.Data, - TokenAmounts: tokensAndAmounts, - SourceTokenData: msg.SourceTokenData, - FeeToken: msg.FeeToken, - MessageId: msg.MessageId, - }) - } - - er.OffchainTokenData = erStruct.OffchainTokenData - er.Proofs = append(er.Proofs, erStruct.Proofs...) - // Unpack will populate with big.Int{false, } for 0 values, - // which is different from the expected big.NewInt(0). Rebuild to the expected value for this case. - er.ProofFlagBits = new(big.Int).SetBytes(erStruct.ProofFlagBits.Bytes()) - return er, nil -} - -// EncodeCommitReport abi encodes an offramp.InternalCommitReport. -func EncodeCommitReport(commitReport commit_store.CommitStoreCommitReport) ([]byte, error) { - return CommitReportArgs.PackValues([]interface{}{commitReport}) -} - -// DecodeCommitReport abi decodes a types.Report to an CommitStoreCommitReport -func DecodeCommitReport(report []byte) (commit_store.CommitStoreCommitReport, error) { - unpacked, err := CommitReportArgs.Unpack(report) - if err != nil { - return commit_store.CommitStoreCommitReport{}, err - } - if len(unpacked) != 1 { - return commit_store.CommitStoreCommitReport{}, errors.New("expected single struct value") - } - - commitReport, ok := unpacked[0].(struct { - PriceUpdates struct { - TokenPriceUpdates []struct { - SourceToken common.Address `json:"sourceToken"` - UsdPerToken *big.Int `json:"usdPerToken"` - } `json:"tokenPriceUpdates"` - DestChainSelector uint64 `json:"destChainSelector"` - UsdPerUnitGas *big.Int `json:"usdPerUnitGas"` - } `json:"priceUpdates"` - Interval struct { - Min uint64 `json:"min"` - Max uint64 `json:"max"` - } `json:"interval"` - MerkleRoot [32]byte `json:"merkleRoot"` - }) - if !ok { - return commit_store.CommitStoreCommitReport{}, errors.Errorf("invalid commit report got %T", unpacked[0]) - } - - var tokenPriceUpdates []commit_store.InternalTokenPriceUpdate - for _, u := range commitReport.PriceUpdates.TokenPriceUpdates { - tokenPriceUpdates = append(tokenPriceUpdates, commit_store.InternalTokenPriceUpdate{ - SourceToken: u.SourceToken, - UsdPerToken: u.UsdPerToken, - }) - } - - return commit_store.CommitStoreCommitReport{ - PriceUpdates: commit_store.InternalPriceUpdates{ - DestChainSelector: commitReport.PriceUpdates.DestChainSelector, - UsdPerUnitGas: commitReport.PriceUpdates.UsdPerUnitGas, - TokenPriceUpdates: tokenPriceUpdates, - }, - Interval: commit_store.CommitStoreInterval{ - Min: commitReport.Interval.Min, - Max: commitReport.Interval.Max, - }, - MerkleRoot: commitReport.MerkleRoot, - }, nil -} - type AbiDefined interface { AbiString() string } diff --git a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go index 4cc5ccfac0..c02ac46016 100644 --- a/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go +++ b/core/services/ocr2/plugins/ccip/abihelpers/abi_helpers_test.go @@ -4,18 +4,10 @@ import ( "fmt" "math" "math/big" - "math/rand" "testing" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/utils" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" - "github.com/test-go/testify/require" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" ) func TestProofFlagToBits(t *testing.T) { @@ -62,52 +54,6 @@ func TestProofFlagToBits(t *testing.T) { } } -func TestCommitReportEncoding(t *testing.T) { - report := commit_store.CommitStoreCommitReport{ - PriceUpdates: commit_store.InternalPriceUpdates{ - TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{ - { - SourceToken: utils.RandomAddress(), - UsdPerToken: big.NewInt(9e18), - }, - }, - DestChainSelector: rand.Uint64(), - UsdPerUnitGas: big.NewInt(2000e9), - }, - MerkleRoot: [32]byte{123}, - Interval: commit_store.CommitStoreInterval{Min: 1, Max: 10}, - } - - encodedReport, err := EncodeCommitReport(report) - require.NoError(t, err) - - decodedReport, err := DecodeCommitReport(encodedReport) - require.NoError(t, err) - require.Equal(t, report, decodedReport) -} - -func TestExecutionReportEncoding(t *testing.T) { - // Note could consider some fancier testing here (fuzz/property) - // but I think that would essentially be testing geth's abi library - // as our encode/decode is a thin wrapper around that. - report := evm_2_evm_offramp.InternalExecutionReport{ - Messages: []evm_2_evm_offramp.InternalEVM2EVMMessage{}, - OffchainTokenData: [][][]byte{{}}, - Proofs: [][32]byte{testutils.Random32Byte()}, - ProofFlagBits: big.NewInt(133), - } - encodeExecutionReport, err := EncodeExecutionReport(evm_2_evm_offramp.InternalExecutionReport{ - Messages: report.Messages, - OffchainTokenData: report.OffchainTokenData, - Proofs: report.Proofs, - ProofFlagBits: report.ProofFlagBits, - }) - require.NoError(t, err) - decodeCommitReport, err := DecodeExecutionReport(encodeExecutionReport) - require.NoError(t, err) - require.Equal(t, report, decodeCommitReport) -} - func TestEvmWord(t *testing.T) { testCases := []struct { inp uint64 diff --git a/core/services/ocr2/plugins/ccip/commit_inflight.go b/core/services/ocr2/plugins/ccip/commit_inflight.go index 3bc66f593c..726bbf6020 100644 --- a/core/services/ocr2/plugins/ccip/commit_inflight.go +++ b/core/services/ocr2/plugins/ccip/commit_inflight.go @@ -7,8 +7,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) const ( @@ -26,12 +26,13 @@ const ( // we are able to obtain high throughput during happy path yet still naturally recover // if a reorg or issue causes onchain reverts. type InflightCommitReport struct { - report commit_store.CommitStoreCommitReport + report ccipdata.CommitStoreReport createdAt time.Time } type InflightPriceUpdate struct { - priceUpdates commit_store.InternalPriceUpdates + gasPrices []ccipdata.GasPrice + tokenPrices []ccipdata.TokenPrice createdAt time.Time epochAndRound uint64 } @@ -67,28 +68,27 @@ func (c *inflightCommitReportsContainer) maxInflightSeqNr() uint64 { return max } -// latestGasPriceUpdate return the latest inflight gas price update or nil if there is no inflight gas price update. -func (c *inflightCommitReportsContainer) getLatestInflightGasPriceUpdate() *update { +// latestInflightGasPriceUpdates returns a map of the latest gas price updates. +func (c *inflightCommitReportsContainer) latestInflightGasPriceUpdates() map[uint64]update { c.locker.RLock() defer c.locker.RUnlock() - var latestGasPriceUpdate *update - var latestEpochAndRound uint64 + latestGasPriceUpdates := make(map[uint64]update) + latestEpochAndRounds := make(map[uint64]uint64) + for _, inflight := range c.inFlightPriceUpdates { - if inflight.priceUpdates.DestChainSelector == 0 { - // Price updates did not include a gas price - continue - } - if latestGasPriceUpdate == nil || inflight.epochAndRound > latestEpochAndRound { - // First price found or found later update, set it - latestGasPriceUpdate = &update{ - timestamp: inflight.createdAt, - value: inflight.priceUpdates.UsdPerUnitGas, + for _, inflightGasUpdate := range inflight.gasPrices { + _, ok := latestGasPriceUpdates[inflightGasUpdate.DestChainSelector] + if !ok || inflight.epochAndRound > latestEpochAndRounds[inflightGasUpdate.DestChainSelector] { + latestGasPriceUpdates[inflightGasUpdate.DestChainSelector] = update{ + value: inflightGasUpdate.Value, + timestamp: inflight.createdAt, + } + latestEpochAndRounds[inflightGasUpdate.DestChainSelector] = inflight.epochAndRound } - latestEpochAndRound = inflight.epochAndRound - continue } } - return latestGasPriceUpdate + + return latestGasPriceUpdates } // latestInflightTokenPriceUpdates returns a map of the latest token price updates @@ -98,20 +98,14 @@ func (c *inflightCommitReportsContainer) latestInflightTokenPriceUpdates() map[c latestTokenPriceUpdates := make(map[common.Address]update) latestEpochAndRounds := make(map[common.Address]uint64) for _, inflight := range c.inFlightPriceUpdates { - for _, inflightTokenUpdate := range inflight.priceUpdates.TokenPriceUpdates { - if _, ok := latestTokenPriceUpdates[inflightTokenUpdate.SourceToken]; !ok { - latestTokenPriceUpdates[inflightTokenUpdate.SourceToken] = update{ - value: inflightTokenUpdate.UsdPerToken, - timestamp: inflight.createdAt, - } - latestEpochAndRounds[inflightTokenUpdate.SourceToken] = inflight.epochAndRound - } - if inflight.epochAndRound > latestEpochAndRounds[inflightTokenUpdate.SourceToken] { - latestTokenPriceUpdates[inflightTokenUpdate.SourceToken] = update{ - value: inflightTokenUpdate.UsdPerToken, + for _, inflightTokenUpdate := range inflight.tokenPrices { + _, ok := latestTokenPriceUpdates[inflightTokenUpdate.Token] + if !ok || inflight.epochAndRound > latestEpochAndRounds[inflightTokenUpdate.Token] { + latestTokenPriceUpdates[inflightTokenUpdate.Token] = update{ + value: inflightTokenUpdate.Value, timestamp: inflight.createdAt, } - latestEpochAndRounds[inflightTokenUpdate.SourceToken] = inflight.epochAndRound + latestEpochAndRounds[inflightTokenUpdate.Token] = inflight.epochAndRound } } } @@ -148,7 +142,7 @@ func (c *inflightCommitReportsContainer) expire(lggr logger.Logger) { if timeSinceUpdate > c.cacheExpiry*PRICE_EXPIRY_MULTIPLIER { // Happy path: inflight report was successfully transmitted onchain, we remove it from inflight and onchain state reflects inflight. // Sad path: inflight report reverts onchain, we remove it from inflight, onchain state does not reflect the chains, so we retry. - lggr.Infow("Inflight price update expired", "updates", inFlightFeeUpdate.priceUpdates) + lggr.Infow("Inflight price update expired", "gasPrices", inFlightFeeUpdate.gasPrices, "tokenPrices", inFlightFeeUpdate.tokenPrices) } else { // If the update is still valid, we keep it in the inflight list. stillInflight = append(stillInflight, inFlightFeeUpdate) @@ -157,7 +151,7 @@ func (c *inflightCommitReportsContainer) expire(lggr logger.Logger) { c.inFlightPriceUpdates = stillInflight } -func (c *inflightCommitReportsContainer) add(lggr logger.Logger, report commit_store.CommitStoreCommitReport, epochAndRound uint64) error { +func (c *inflightCommitReportsContainer) add(lggr logger.Logger, report ccipdata.CommitStoreReport, epochAndRound uint64) error { c.locker.Lock() defer c.locker.Unlock() @@ -170,10 +164,11 @@ func (c *inflightCommitReportsContainer) add(lggr logger.Logger, report commit_s } } - if report.PriceUpdates.DestChainSelector != 0 || len(report.PriceUpdates.TokenPriceUpdates) != 0 { - lggr.Infow("Adding to inflight fee updates", "priceUpdates", report.PriceUpdates) + if len(report.GasPrices) != 0 || len(report.TokenPrices) != 0 { + lggr.Infow("Adding to inflight fee updates", "gasPrices", report.GasPrices, "tokenPrices", report.TokenPrices) c.inFlightPriceUpdates = append(c.inFlightPriceUpdates, InflightPriceUpdate{ - priceUpdates: report.PriceUpdates, + gasPrices: report.GasPrices, + tokenPrices: report.TokenPrices, createdAt: time.Now(), epochAndRound: epochAndRound, }) diff --git a/core/services/ocr2/plugins/ccip/commit_inflight_test.go b/core/services/ocr2/plugins/ccip/commit_inflight_test.go index f5c926134b..f28856afc0 100644 --- a/core/services/ocr2/plugins/ccip/commit_inflight_test.go +++ b/core/services/ocr2/plugins/ccip/commit_inflight_test.go @@ -10,9 +10,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -21,51 +21,77 @@ func TestCommitInflight(t *testing.T) { c := newInflightCommitReportsContainer(time.Hour) c.inFlightPriceUpdates = append(c.inFlightPriceUpdates, InflightPriceUpdate{ - priceUpdates: commit_store.InternalPriceUpdates{DestChainSelector: 0}, // skipped when destChainSelector is 0 + gasPrices: []ccipdata.GasPrice{}, createdAt: time.Now(), epochAndRound: ccipcalc.MergeEpochAndRound(2, 4), }) // Initially should be empty - assert.Nil(t, c.getLatestInflightGasPriceUpdate()) + inflightGasUpdates := c.latestInflightGasPriceUpdates() + assert.Equal(t, 0, len(inflightGasUpdates)) assert.Equal(t, uint64(0), c.maxInflightSeqNr()) epochAndRound := uint64(1) // Add a single report inflight root1 := utils.Keccak256Fixed(hexutil.MustDecode("0xaa")) - require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{Interval: commit_store.CommitStoreInterval{Min: 1, Max: 2}, MerkleRoot: root1}, epochAndRound)) - assert.Nil(t, c.getLatestInflightGasPriceUpdate()) + require.NoError(t, c.add(lggr, ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 2}, + MerkleRoot: root1, + GasPrices: []ccipdata.GasPrice{ + {DestChainSelector: 123, Value: big.NewInt(999)}, + }, + }, epochAndRound)) + inflightGasUpdates = c.latestInflightGasPriceUpdates() + assert.Equal(t, 1, len(inflightGasUpdates)) + assert.Equal(t, big.NewInt(999), inflightGasUpdates[123].value) assert.Equal(t, uint64(2), c.maxInflightSeqNr()) epochAndRound++ // Add another price report root2 := utils.Keccak256Fixed(hexutil.MustDecode("0xab")) - require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{Interval: commit_store.CommitStoreInterval{Min: 3, Max: 4}, MerkleRoot: root2}, epochAndRound)) - assert.Nil(t, c.getLatestInflightGasPriceUpdate()) + require.NoError(t, c.add(lggr, ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: 3, Max: 4}, + MerkleRoot: root2, + GasPrices: []ccipdata.GasPrice{ + {DestChainSelector: 321, Value: big.NewInt(888)}, + }, + }, epochAndRound)) + inflightGasUpdates = c.latestInflightGasPriceUpdates() + assert.Equal(t, 2, len(inflightGasUpdates)) + assert.Equal(t, big.NewInt(999), inflightGasUpdates[123].value) + assert.Equal(t, big.NewInt(888), inflightGasUpdates[321].value) assert.Equal(t, uint64(4), c.maxInflightSeqNr()) epochAndRound++ // Add gas price updates - require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{PriceUpdates: commit_store.InternalPriceUpdates{ - DestChainSelector: uint64(1), - UsdPerUnitGas: big.NewInt(1), - }}, epochAndRound)) - latest := c.getLatestInflightGasPriceUpdate() - assert.Equal(t, big.NewInt(1), latest.value) + require.NoError(t, c.add(lggr, ccipdata.CommitStoreReport{ + GasPrices: []ccipdata.GasPrice{ + { + DestChainSelector: uint64(1), + Value: big.NewInt(1), + }, + }}, epochAndRound)) + + inflightGasUpdates = c.latestInflightGasPriceUpdates() + assert.Equal(t, 3, len(inflightGasUpdates)) + assert.Equal(t, big.NewInt(999), inflightGasUpdates[123].value) + assert.Equal(t, big.NewInt(888), inflightGasUpdates[321].value) + assert.Equal(t, big.NewInt(1), inflightGasUpdates[1].value) assert.Equal(t, uint64(4), c.maxInflightSeqNr()) epochAndRound++ // Add a token price update token := common.HexToAddress("0xa") - require.NoError(t, c.add(lggr, commit_store.CommitStoreCommitReport{PriceUpdates: commit_store.InternalPriceUpdates{ - TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{ + require.NoError(t, c.add(lggr, ccipdata.CommitStoreReport{ + TokenPrices: []ccipdata.TokenPrice{ { - SourceToken: token, - UsdPerToken: big.NewInt(10), + Token: token, + Value: big.NewInt(10), }, }, - }}, epochAndRound)) + GasPrices: []ccipdata.GasPrice{}, + }, epochAndRound)) // Apply cache price to existing latestInflightTokenPriceUpdates := c.latestInflightTokenPriceUpdates() require.Equal(t, len(latestInflightTokenPriceUpdates), 1) @@ -73,12 +99,14 @@ func TestCommitInflight(t *testing.T) { // larger epoch and round overrides existing price update c.inFlightPriceUpdates = append(c.inFlightPriceUpdates, InflightPriceUpdate{ - priceUpdates: commit_store.InternalPriceUpdates{ - TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{ - {SourceToken: token, UsdPerToken: big.NewInt(9999)}, + tokenPrices: []ccipdata.TokenPrice{ + {Token: token, Value: big.NewInt(9999)}, + }, + gasPrices: []ccipdata.GasPrice{ + { + DestChainSelector: uint64(1), + Value: big.NewInt(999), }, - DestChainSelector: uint64(1), - UsdPerUnitGas: big.NewInt(999), }, createdAt: time.Now(), epochAndRound: ccipcalc.MergeEpochAndRound(999, 99), @@ -86,6 +114,11 @@ func TestCommitInflight(t *testing.T) { latestInflightTokenPriceUpdates = c.latestInflightTokenPriceUpdates() require.Equal(t, len(latestInflightTokenPriceUpdates), 1) assert.Equal(t, big.NewInt(9999), latestInflightTokenPriceUpdates[token].value) + inflightGasUpdates = c.latestInflightGasPriceUpdates() + assert.Equal(t, 3, len(inflightGasUpdates)) + assert.Equal(t, big.NewInt(999), inflightGasUpdates[123].value) + assert.Equal(t, big.NewInt(888), inflightGasUpdates[321].value) + assert.Equal(t, big.NewInt(999), inflightGasUpdates[1].value) } func Test_inflightCommitReportsContainer_expire(t *testing.T) { @@ -93,22 +126,22 @@ func Test_inflightCommitReportsContainer_expire(t *testing.T) { cacheExpiry: time.Minute, inFlight: map[[32]byte]InflightCommitReport{ common.HexToHash("1"): { - report: commit_store.CommitStoreCommitReport{}, + report: ccipdata.CommitStoreReport{}, createdAt: time.Now().Add(-5 * time.Minute), }, common.HexToHash("2"): { - report: commit_store.CommitStoreCommitReport{}, + report: ccipdata.CommitStoreReport{}, createdAt: time.Now().Add(-10 * time.Second), }, }, inFlightPriceUpdates: []InflightPriceUpdate{ { - priceUpdates: commit_store.InternalPriceUpdates{DestChainSelector: 100}, + gasPrices: []ccipdata.GasPrice{{DestChainSelector: 100, Value: big.NewInt(0)}}, createdAt: time.Now().Add(-PRICE_EXPIRY_MULTIPLIER * time.Minute), epochAndRound: ccipcalc.MergeEpochAndRound(10, 5), }, { - priceUpdates: commit_store.InternalPriceUpdates{DestChainSelector: 200}, + gasPrices: []ccipdata.GasPrice{{DestChainSelector: 200, Value: big.NewInt(0)}}, createdAt: time.Now().Add(-PRICE_EXPIRY_MULTIPLIER * time.Second), epochAndRound: ccipcalc.MergeEpochAndRound(20, 5), }, diff --git a/core/services/ocr2/plugins/ccip/commit_plugin.go b/core/services/ocr2/plugins/ccip/commit_plugin.go index 8691c4a99b..813ced71c5 100644 --- a/core/services/ocr2/plugins/ccip/commit_plugin.go +++ b/core/services/ocr2/plugins/ccip/commit_plugin.go @@ -3,9 +3,9 @@ package ccip import ( "context" "encoding/json" - "fmt" "strconv" + "github.com/Masterminds/semver/v3" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" @@ -14,273 +14,168 @@ import ( libocr2 "github.com/smartcontractkit/libocr/offchainreporting2plus" relaylogger "github.com/smartcontractkit/chainlink-relay/pkg/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/contractutil" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/oraclelib" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" - "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/contractutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/oraclelib" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/promwrapper" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" ) -const ( - COMMIT_PRICE_UPDATES = "Commit price updates" - COMMIT_CCIP_SENDS = "Commit ccip sends" -) +type BackfillArgs struct { + sourceLP, destLP logpoller.LogPoller + sourceStartBlock, destStartBlock int64 +} -func NewCommitServices(lggr logger.Logger, jb job.Job, chainSet evm.LegacyChainContainer, new bool, pr pipeline.Runner, argsNoPlugin libocr2.OCR2OracleArgs, logError func(string), qopts ...pg.QOpt) ([]job.ServiceCtx, error) { +func jobSpecToCommitPluginConfig(lggr logger.Logger, jb job.Job, pr pipeline.Runner, chainSet evm.LegacyChainContainer, qopts ...pg.QOpt) (*CommitPluginStaticConfig, *BackfillArgs, error) { + if jb.OCR2OracleSpec == nil { + return nil, nil, errors.New("spec is nil") + } spec := jb.OCR2OracleSpec - var pluginConfig ccipconfig.CommitPluginJobSpecConfig err := json.Unmarshal(spec.PluginConfig.Bytes(), &pluginConfig) if err != nil { - return nil, err + return nil, nil, err } chainIDInterface, ok := spec.RelayConfig["chainID"] if !ok { - return nil, errors.New("chainID must be provided in relay config") + return nil, nil, errors.New("chainID must be provided in relay config") } destChainID := int64(chainIDInterface.(float64)) destChain, err := chainSet.Get(strconv.FormatInt(destChainID, 10)) if err != nil { - return nil, errors.Wrap(err, "get chainset") + return nil, nil, errors.Wrap(err, "get chainset") } - commitStore, err := contractutil.LoadCommitStore(common.HexToAddress(spec.ContractID), CommitPluginLabel, destChain.Client()) + commitStore, _, err := contractutil.LoadCommitStore(common.HexToAddress(spec.ContractID), CommitPluginLabel, destChain.Client()) if err != nil { - return nil, errors.Wrap(err, "failed loading commitStore") + return nil, nil, errors.Wrap(err, "failed loading commitStore") } staticConfig, err := commitStore.GetStaticConfig(&bind.CallOpts{}) if err != nil { - return nil, errors.Wrap(err, "failed getting the static config from the commitStore") + return nil, nil, errors.Wrap(err, "failed getting the static config from the commitStore") } chainId, err := chainselectors.ChainIdFromSelector(staticConfig.SourceChainSelector) if err != nil { - return nil, err + return nil, nil, err } sourceChain, err := chainSet.Get(strconv.FormatUint(chainId, 10)) if err != nil { - return nil, errors.Wrap(err, "unable to open source chain") + return nil, nil, errors.Wrap(err, "unable to open source chain") } - offRamp, err := contractutil.LoadOffRamp(common.HexToAddress(pluginConfig.OffRamp), CommitPluginLabel, destChain.Client()) + commitLggr := lggr.Named("CCIPCommit").With( + "sourceChain", ChainName(int64(chainId)), + "destChain", ChainName(destChainID)) + pipelinePriceGetter, err := pricegetter.NewPipelineGetter(pluginConfig.TokenPricesUSDPipeline, pr, jb.ID, jb.ExternalJobID, jb.Name.ValueOrZero(), lggr) if err != nil { - return nil, errors.Wrap(err, "failed loading offRamp") + return nil, nil, err } - onRamp, err := contractutil.LoadOnRamp(staticConfig.OnRamp, CommitPluginLabel, sourceChain.Client()) + + // Load all the readers relevant for this plugin. + onRampReader, err := ccipdata.NewOnRampReader(commitLggr, staticConfig.SourceChainSelector, staticConfig.ChainSelector, staticConfig.OnRamp, sourceChain.LogPoller(), sourceChain.Client(), sourceChain.Config().EVM().FinalityTagEnabled(), qopts...) if err != nil { - return nil, errors.Wrap(err, "failed loading onRamp") + return nil, nil, errors.Wrap(err, "failed onramp reader") } - priceGetterObject, err := pricegetter.NewPipelineGetter(pluginConfig.TokenPricesUSDPipeline, pr, jb.ID, jb.ExternalJobID, jb.Name.ValueOrZero(), lggr) + offRampReader, err := ccipdata.NewOffRampReader(commitLggr, common.HexToAddress(pluginConfig.OffRamp), destChain.Client(), destChain.LogPoller(), destChain.GasEstimator()) if err != nil { - return nil, err + return nil, nil, errors.Wrap(err, "failed offramp reader") } - dynamicOnRampConfig, err := contractutil.LoadOnRampDynamicConfig(onRamp, sourceChain.Client()) + commitStoreReader, err := ccipdata.NewCommitStoreReader(commitLggr, common.HexToAddress(spec.ContractID), destChain.Client(), destChain.LogPoller(), sourceChain.GasEstimator()) if err != nil { - return nil, err + return nil, nil, errors.Wrap(err, "failed commit reader") } - sourceRouter, err := router.NewRouter(dynamicOnRampConfig.Router, sourceChain.Client()) + + onRampRouterAddr, err := onRampReader.RouterAddress() if err != nil { - return nil, err + return nil, nil, err + } + sourceRouter, err := router.NewRouter(onRampRouterAddr, sourceChain.Client()) + if err != nil { + return nil, nil, err } sourceNative, err := sourceRouter.GetWrappedNative(nil) if err != nil { - return nil, err + return nil, nil, err } - - leafHasher := hashlib.NewLeafHasher(staticConfig.SourceChainSelector, staticConfig.ChainSelector, onRamp.Address(), hashlib.NewKeccakCtx()) - // Note that lggr already has the jobName and contractID (commit store) - commitLggr := lggr.Named("CCIPCommit").With( - "sourceChain", ChainName(int64(chainId)), - "destChain", ChainName(destChainID)) - wrappedPluginFactory := NewCommitReportingPluginFactory( - CommitPluginConfig{ + lggr.Infow("NewCommitServices", + "pluginConfig", pluginConfig, + "staticConfig", staticConfig, + // TODO bring back + //"dynamicOnRampConfig", dynamicOnRampConfig, + "sourceNative", sourceNative, + "sourceRouter", sourceRouter.Address()) + return &CommitPluginStaticConfig{ lggr: commitLggr, - sourceLP: sourceChain.LogPoller(), destLP: destChain.LogPoller(), - sourceReader: ccipdata.NewLogPollerReader(sourceChain.LogPoller(), commitLggr, sourceChain.Client()), - destReader: ccipdata.NewLogPollerReader(destChain.LogPoller(), commitLggr, destChain.Client()), - offRamp: offRamp, - onRampAddress: onRamp.Address(), - priceGetter: priceGetterObject, + onRampReader: onRampReader, + offRamp: offRampReader, + priceGetter: pipelinePriceGetter, sourceNative: sourceNative, - sourceFeeEstimator: sourceChain.GasEstimator(), sourceChainSelector: staticConfig.SourceChainSelector, destClient: destChain.Client(), - sourceClient: sourceChain.Client(), - commitStore: commitStore, - leafHasher: leafHasher, - checkFinalityTags: sourceChain.Config().EVM().FinalityTagEnabled(), - }) + commitStore: commitStoreReader, + }, &BackfillArgs{ + sourceLP: sourceChain.LogPoller(), + destLP: destChain.LogPoller(), + sourceStartBlock: pluginConfig.SourceStartBlock, + destStartBlock: pluginConfig.DestStartBlock, + }, nil +} - err = wrappedPluginFactory.UpdateLogPollerFilters(utils.ZeroAddress, qopts...) +func NewCommitServices(lggr logger.Logger, jb job.Job, chainSet evm.LegacyChainContainer, new bool, pr pipeline.Runner, argsNoPlugin libocr2.OCR2OracleArgs, logError func(string), qopts ...pg.QOpt) ([]job.ServiceCtx, error) { + pluginConfig, backfillArgs, err := jobSpecToCommitPluginConfig(lggr, jb, pr, chainSet, qopts...) if err != nil { return nil, err } + wrappedPluginFactory := NewCommitReportingPluginFactory(*pluginConfig) - argsNoPlugin.ReportingPluginFactory = promwrapper.NewPromFactory(wrappedPluginFactory, "CCIPCommit", string(spec.Relay), destChain.ID()) - argsNoPlugin.Logger = relaylogger.NewOCRWrapper(commitLggr, true, logError) + argsNoPlugin.ReportingPluginFactory = promwrapper.NewPromFactory(wrappedPluginFactory, "CCIPCommit", jb.OCR2OracleSpec.Relay, pluginConfig.destChainEVMID) + argsNoPlugin.Logger = relaylogger.NewOCRWrapper(pluginConfig.lggr, true, logError) oracle, err := libocr2.NewOracle(argsNoPlugin) if err != nil { return nil, err } - commitLggr.Infow("NewCommitServices", - "pluginConfig", pluginConfig, - "staticConfig", staticConfig, - "dynamicOnRampConfig", dynamicOnRampConfig, - "sourceNative", sourceNative, - "sourceRouter", sourceRouter.Address()) // If this is a brand-new job, then we make use of the start blocks. If not then we're rebooting and log poller will pick up where we left off. if new { return []job.ServiceCtx{oraclelib.NewBackfilledOracle( - commitLggr, - sourceChain.LogPoller(), - destChain.LogPoller(), - pluginConfig.SourceStartBlock, - pluginConfig.DestStartBlock, + pluginConfig.lggr, + backfillArgs.sourceLP, + backfillArgs.destLP, + backfillArgs.sourceStartBlock, + backfillArgs.destStartBlock, job.NewServiceAdapter(oracle)), }, nil } return []job.ServiceCtx{job.NewServiceAdapter(oracle)}, nil } -// CommitReportToEthTxMeta generates a txmgr.EthTxMeta from the given commit report. -// sequence numbers of the committed messages will be added to tx metadata -func CommitReportToEthTxMeta(report []byte) (*txmgr.TxMeta, error) { - commitReport, err := abihelpers.DecodeCommitReport(report) - if err != nil { - return nil, err - } - n := int(commitReport.Interval.Max-commitReport.Interval.Min) + 1 - seqRange := make([]uint64, n) - for i := 0; i < n; i++ { - seqRange[i] = uint64(i) + commitReport.Interval.Min - } - return &txmgr.TxMeta{ - SeqNumbers: seqRange, - }, nil -} - -func getCommitPluginSourceLpFilters(onRamp common.Address) []logpoller.Filter { - return []logpoller.Filter{ - { - Name: logpoller.FilterName(COMMIT_CCIP_SENDS, onRamp.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.SendRequested}, - Addresses: []common.Address{onRamp}, - }, - } -} - -func getCommitPluginDestLpFilters(priceRegistry common.Address, offRamp common.Address) []logpoller.Filter { - return []logpoller.Filter{ - { - Name: logpoller.FilterName(COMMIT_PRICE_UPDATES, priceRegistry.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.UsdPerUnitGasUpdated, abihelpers.EventSignatures.UsdPerTokenUpdated}, - Addresses: []common.Address{priceRegistry}, - }, - { - Name: logpoller.FilterName(FEE_TOKEN_ADDED, priceRegistry), - EventSigs: []common.Hash{abihelpers.EventSignatures.FeeTokenAdded}, - Addresses: []common.Address{priceRegistry}, - }, - { - Name: logpoller.FilterName(FEE_TOKEN_REMOVED, priceRegistry), - EventSigs: []common.Hash{abihelpers.EventSignatures.FeeTokenRemoved}, - Addresses: []common.Address{priceRegistry}, - }, - { - Name: logpoller.FilterName(EXEC_TOKEN_POOL_ADDED, offRamp), - EventSigs: []common.Hash{abihelpers.EventSignatures.PoolAdded}, - Addresses: []common.Address{offRamp}, - }, - { - Name: logpoller.FilterName(EXEC_TOKEN_POOL_REMOVED, offRamp), - EventSigs: []common.Hash{abihelpers.EventSignatures.PoolRemoved}, - Addresses: []common.Address{offRamp}, - }, - } +func CommitReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (func(report []byte) (*txmgr.TxMeta, error), error) { + return ccipdata.CommitReportToEthTxMeta(typ, ver) } // UnregisterCommitPluginLpFilters unregisters all the registered filters for both source and dest chains. -func UnregisterCommitPluginLpFilters(ctx context.Context, spec *job.OCR2OracleSpec, chainSet evm.LegacyChainContainer, qopts ...pg.QOpt) error { - if spec == nil { - return errors.New("spec is nil") - } - if !common.IsHexAddress(spec.ContractID) { - return fmt.Errorf("invalid contract id address: %s", spec.ContractID) - } - - var pluginConfig ccipconfig.CommitPluginJobSpecConfig - err := json.Unmarshal(spec.PluginConfig.Bytes(), &pluginConfig) +// NOTE: The transaction MUST be used here for CLO's monster tx to function as expected +// https://github.com/smartcontractkit/ccip/blob/68e2197472fb017dd4e5630d21e7878d58bc2a44/core/services/feeds/service.go#L716 +// TODO once that transaction is broken up, we should be able to simply rely on oracle.Close() to cleanup the filters. +// Until then we have to deterministically reload the readers from the spec (and thus their filters) and close them. +func UnregisterCommitPluginLpFilters(ctx context.Context, lggr logger.Logger, jb job.Job, pr pipeline.Runner, chainSet evm.LegacyChainContainer, qopts ...pg.QOpt) error { + commitPluginConfig, _, err := jobSpecToCommitPluginConfig(lggr, jb, pr, chainSet) if err != nil { - return err - } - - destChainIDInterface, ok := spec.RelayConfig["chainID"] - if !ok { - return errors.New("chainID must be provided in relay config") - } - destChainIDf64, is := destChainIDInterface.(float64) - if !is { - return fmt.Errorf("chain id '%v' is not float64", destChainIDInterface) - } - destChainID := int64(destChainIDf64) - destChain, err := chainSet.Get(strconv.FormatInt(destChainID, 10)) - if err != nil { - return err - } - commitStore, err := contractutil.LoadCommitStore(common.HexToAddress(spec.ContractID), CommitPluginLabel, destChain.Client()) - if err != nil { - return err - } - staticConfig, err := commitStore.GetStaticConfig(&bind.CallOpts{}) - if err != nil { - return err - } - chainId, err := chainselectors.ChainIdFromSelector(staticConfig.SourceChainSelector) - if err != nil { - return err - } - sourceChain, err := chainSet.Get(strconv.FormatUint(chainId, 10)) - if err != nil { - return err - } - return unregisterCommitPluginFilters(ctx, sourceChain.LogPoller(), destChain.LogPoller(), commitStore, common.HexToAddress(pluginConfig.OffRamp), qopts...) -} - -func unregisterCommitPluginFilters(ctx context.Context, sourceLP, destLP logpoller.LogPoller, destCommitStore commit_store.CommitStoreInterface, offRamp common.Address, qopts ...pg.QOpt) error { - staticCfg, err := destCommitStore.GetStaticConfig(&bind.CallOpts{Context: ctx}) - if err != nil { - return err + return errors.New("spec is nil") } - - dynamicCfg, err := destCommitStore.GetDynamicConfig(&bind.CallOpts{Context: ctx}) - if err != nil { + if err := commitPluginConfig.onRampReader.Close(qopts...); err != nil { return err } - - if err := logpollerutil.UnregisterLpFilters( - sourceLP, - getCommitPluginSourceLpFilters(staticCfg.OnRamp), - qopts..., - ); err != nil { + if err := commitPluginConfig.commitStore.Close(qopts...); err != nil { return err } - - return logpollerutil.UnregisterLpFilters( - destLP, - getCommitPluginDestLpFilters(dynamicCfg.PriceRegistry, offRamp), - qopts..., - ) + return commitPluginConfig.offRamp.Close(qopts...) } diff --git a/core/services/ocr2/plugins/ccip/commit_plugin_test.go b/core/services/ocr2/plugins/ccip/commit_plugin_test.go index a7a53dd32b..d1c6aa5b94 100644 --- a/core/services/ocr2/plugins/ccip/commit_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/commit_plugin_test.go @@ -4,24 +4,19 @@ import ( "context" "fmt" "strconv" - "sync" "testing" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - mocklp "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" evmmocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/mocks" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + pipelinemocks "github.com/smartcontractkit/chainlink/v2/core/services/pipeline/mocks" "github.com/smartcontractkit/chainlink/v2/core/utils" ) func TestGetCommitPluginFilterNamesFromSpec(t *testing.T) { + lggr := logger.TestLogger(t) testCases := []struct { description string spec *job.OCR2OracleSpec @@ -63,6 +58,7 @@ func TestGetCommitPluginFilterNamesFromSpec(t *testing.T) { for _, tc := range testCases { t.Run(tc.description, func(t *testing.T) { chainSet := &evmmocks.LegacyChainContainer{} + prMock := &pipelinemocks.Runner{} if tc.spec != nil { if chainID, ok := tc.spec.RelayConfig["chainID"]; ok { @@ -72,7 +68,7 @@ func TestGetCommitPluginFilterNamesFromSpec(t *testing.T) { } } - err := UnregisterCommitPluginLpFilters(context.Background(), tc.spec, chainSet) + err := UnregisterCommitPluginLpFilters(context.Background(), lggr, job.Job{OCR2OracleSpec: tc.spec}, prMock, chainSet) if tc.expectingErr { assert.Error(t, err) } else { @@ -84,84 +80,3 @@ func TestGetCommitPluginFilterNamesFromSpec(t *testing.T) { } } - -func TestGetCommitPluginFilterNames(t *testing.T) { - onRampAddr := common.HexToAddress("0xdafea492d9c6733ae3d56b7ed1adb60692c98bc2") - priceRegAddr := common.HexToAddress("0xdafea492d9c6733ae3d56b7ed1adb60692c98bc3") - offRampAddr := common.HexToAddress("0xDAFeA492D9c6733Ae3D56b7eD1AdB60692C98BC4") - - mockCommitStore, _ := testhelpers.NewFakeCommitStore(t, 1) - mockCommitStore.SetStaticConfig(commit_store.CommitStoreStaticConfig{OnRamp: onRampAddr}) - mockCommitStore.SetDynamicConfig(commit_store.CommitStoreDynamicConfig{PriceRegistry: priceRegAddr}) - - srcLP := mocklp.NewLogPoller(t) - dstLP := mocklp.NewLogPoller(t) - - srcLP.On("UnregisterFilter", "Commit ccip sends - 0xdafea492D9c6733aE3d56B7ED1aDb60692C98bc2", mock.Anything).Return(nil) - dstLP.On("UnregisterFilter", "Commit price updates - 0xdafEa492d9C6733aE3D56b7eD1aDb60692c98bc3", mock.Anything).Return(nil) - dstLP.On("UnregisterFilter", "Fee token added - 0xdafEa492d9C6733aE3D56b7eD1aDb60692c98bc3", mock.Anything).Return(nil) - dstLP.On("UnregisterFilter", "Fee token removed - 0xdafEa492d9C6733aE3D56b7eD1aDb60692c98bc3", mock.Anything).Return(nil) - dstLP.On("UnregisterFilter", "Token pool added - 0xDAFeA492D9c6733Ae3D56b7eD1AdB60692C98BC4", mock.Anything).Return(nil) - dstLP.On("UnregisterFilter", "Token pool removed - 0xDAFeA492D9c6733Ae3D56b7eD1AdB60692C98BC4", mock.Anything).Return(nil) - - err := unregisterCommitPluginFilters(context.Background(), srcLP, dstLP, mockCommitStore, offRampAddr) - assert.NoError(t, err) - - srcLP.AssertExpectations(t) - dstLP.AssertExpectations(t) -} - -func Test_updateCommitPluginLogPollerFilters(t *testing.T) { - srcLP := &mocklp.LogPoller{} - dstLP := &mocklp.LogPoller{} - - onRampAddr := common.HexToAddress("0xdafea492d9c6733ae3d56b7ed1adb60692c98bc2") - priceRegAddr := common.HexToAddress("0xdafea492d9c6733ae3d56b7ed1adb60692c98bc3") - offRampAddr := common.HexToAddress("0xDAFeA492D9c6733Ae3D56b7eD1AdB60692C98BC4") - offRamp := &mock_contracts.EVM2EVMOffRampInterface{} - offRamp.On("Address").Return(offRampAddr) - - newDestFilters := getCommitPluginDestLpFilters(priceRegAddr, offRampAddr) - newSrcFilters := getCommitPluginSourceLpFilters(onRampAddr) - - rf := &CommitReportingPluginFactory{ - config: CommitPluginConfig{ - sourceLP: srcLP, - destLP: dstLP, - onRampAddress: onRampAddr, - offRamp: offRamp, - }, - destChainFilters: []logpoller.Filter{ - {Name: "a"}, - {Name: "b"}, - }, - sourceChainFilters: []logpoller.Filter{ - {Name: newSrcFilters[0].Name}, // should not be touched, since it's already registered - {Name: "c"}, - {Name: "d"}, - }, - filtersMu: &sync.Mutex{}, - } - - // make sure existing filters get unregistered - for _, f := range rf.destChainFilters { - dstLP.On("UnregisterFilter", f.Name, mock.Anything).Return(nil) - } - for _, f := range rf.sourceChainFilters[1:] { // skip the first one, which should not be unregistered - srcLP.On("UnregisterFilter", f.Name, mock.Anything).Return(nil) - } - - // make sure new filters are registered - for _, f := range newDestFilters { - dstLP.On("RegisterFilter", f).Return(nil) - } - for _, f := range newSrcFilters[1:] { // skip the first one, which should not be registered - srcLP.On("RegisterFilter", f).Return(nil) - } - - err := rf.UpdateLogPollerFilters(priceRegAddr) - assert.NoError(t, err) - - srcLP.AssertExpectations(t) - dstLP.AssertExpectations(t) -} diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go index fd68641bb5..bb24464574 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin.go @@ -10,33 +10,23 @@ import ( "sync" "time" - "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "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" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/contractutil" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" "github.com/smartcontractkit/chainlink/v2/core/utils/mathutil" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/merklemulti" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) const ( @@ -58,91 +48,118 @@ type update struct { value *big.Int } -type CommitPluginConfig struct { - lggr logger.Logger - sourceLP, destLP logpoller.LogPoller - sourceReader ccipdata.Reader - destReader ccipdata.Reader - offRamp evm_2_evm_offramp.EVM2EVMOffRampInterface - onRampAddress common.Address - commitStore commit_store.CommitStoreInterface - priceGetter pricegetter.PriceGetter - sourceChainSelector uint64 - sourceNative common.Address - sourceFeeEstimator gas.EvmFeeEstimator - sourceClient, destClient evmclient.Client - leafHasher hashlib.LeafHasherInterface[[32]byte] - checkFinalityTags bool +type CommitPluginStaticConfig struct { + lggr logger.Logger + // Source + onRampReader ccipdata.OnRampReader + sourceChainSelector uint64 + sourceNative common.Address + // Dest + destLP logpoller.LogPoller + offRamp ccipdata.OffRampReader + commitStore ccipdata.CommitStoreReader + destClient evmclient.Client + destChainEVMID *big.Int + // Offchain + priceGetter pricegetter.PriceGetter } type CommitReportingPlugin struct { - config CommitPluginConfig - F int - lggr logger.Logger - inflightReports *inflightCommitReportsContainer - destPriceRegistry price_registry.PriceRegistryInterface - offchainConfig ccipconfig.CommitOffchainConfig - onchainConfig ccipconfig.CommitOnchainConfig - tokenDecimalsCache cache.AutoSync[map[common.Address]uint8] + lggr logger.Logger + // Source + onRampReader ccipdata.OnRampReader + sourceChainSelector uint64 + sourceNative common.Address + gasPriceEstimator prices.GasPriceEstimatorCommit + // Dest + commitStoreReader ccipdata.CommitStoreReader + destPriceRegistryReader ccipdata.PriceRegistryReader + offchainConfig ccipdata.CommitOffchainConfig + tokenDecimalsCache cache.AutoSync[map[common.Address]uint8] + F int + // Offchain + priceGetter pricegetter.PriceGetter + // State + inflightReports *inflightCommitReportsContainer } type CommitReportingPluginFactory struct { - config CommitPluginConfig - - // We keep track of the registered filters - sourceChainFilters []logpoller.Filter - destChainFilters []logpoller.Filter - filtersMu *sync.Mutex + // Configuration derived from the job spec which does not change + // between plugin instances (ie between SetConfigs onchain) + config CommitPluginStaticConfig + + // Dynamic readers + readersMu *sync.Mutex + destPriceRegReader ccipdata.PriceRegistryReader + destPriceRegAddr common.Address } // NewCommitReportingPluginFactory return a new CommitReportingPluginFactory. -func NewCommitReportingPluginFactory(config CommitPluginConfig) *CommitReportingPluginFactory { +func NewCommitReportingPluginFactory(config CommitPluginStaticConfig) *CommitReportingPluginFactory { return &CommitReportingPluginFactory{ config: config, - filtersMu: &sync.Mutex{}, + readersMu: &sync.Mutex{}, } } -// NewReportingPlugin returns the ccip CommitReportingPlugin and satisfies the ReportingPluginFactory interface. -func (rf *CommitReportingPluginFactory) NewReportingPlugin(config types.ReportingPluginConfig) (types.ReportingPlugin, types.ReportingPluginInfo, error) { - onchainConfig, err := abihelpers.DecodeAbiStruct[ccipconfig.CommitOnchainConfig](config.OnchainConfig) +func (rf *CommitReportingPluginFactory) UpdateDynamicReaders(newPriceRegAddr common.Address) error { + rf.readersMu.Lock() + defer rf.readersMu.Unlock() + // TODO: Investigate use of Close() to cleanup. + // TODO: a true price registry upgrade on an existing lane may want some kind of start block in its config? Right now we + // essentially assume that plugins don't care about historical price reg logs. + if rf.destPriceRegAddr == newPriceRegAddr { + // No-op + return nil + } + // Close old reader if present and open new reader if address changed + if rf.destPriceRegReader != nil { + if err := rf.destPriceRegReader.Close(); err != nil { + return err + } + } + destPriceRegistryReader, err := ccipdata.NewPriceRegistryReader(rf.config.lggr, newPriceRegAddr, rf.config.destLP, rf.config.destClient) if err != nil { - return nil, types.ReportingPluginInfo{}, err + return err } - offchainConfig, err := ccipconfig.DecodeOffchainConfig[ccipconfig.CommitOffchainConfig](config.OffchainConfig) + rf.destPriceRegReader = destPriceRegistryReader + rf.destPriceRegAddr = newPriceRegAddr + return nil +} + +// NewReportingPlugin returns the ccip CommitReportingPlugin and satisfies the ReportingPluginFactory interface. +func (rf *CommitReportingPluginFactory) NewReportingPlugin(config types.ReportingPluginConfig) (types.ReportingPlugin, types.ReportingPluginInfo, error) { + destPriceReg, err := rf.config.commitStore.ChangeConfig(config.OnchainConfig, config.OffchainConfig) if err != nil { return nil, types.ReportingPluginInfo{}, err } - destPriceRegistry, err := price_registry.NewPriceRegistry(onchainConfig.PriceRegistry, rf.config.destClient) - if err != nil { + if err = rf.UpdateDynamicReaders(destPriceReg); err != nil { return nil, types.ReportingPluginInfo{}, err } - if err = rf.UpdateLogPollerFilters(onchainConfig.PriceRegistry); err != nil { + if err != nil { return nil, types.ReportingPluginInfo{}, err } - rf.config.lggr.Infow("NewReportingPlugin", - "offchainConfig", offchainConfig, - "onchainConfig", onchainConfig, - ) - return &CommitReportingPlugin{ - config: rf.config, - F: config.F, - lggr: rf.config.lggr.Named("CommitReportingPlugin"), - inflightReports: newInflightCommitReportsContainer(offchainConfig.InflightCacheExpiry.Duration()), - destPriceRegistry: destPriceRegistry, - onchainConfig: onchainConfig, - offchainConfig: offchainConfig, + sourceChainSelector: rf.config.sourceChainSelector, + sourceNative: rf.config.sourceNative, + onRampReader: rf.config.onRampReader, + commitStoreReader: rf.config.commitStore, + priceGetter: rf.config.priceGetter, + F: config.F, + lggr: rf.config.lggr.Named("CommitReportingPlugin"), + inflightReports: newInflightCommitReportsContainer(rf.config.commitStore.OffchainConfig().InflightCacheExpiry), + destPriceRegistryReader: rf.destPriceRegReader, tokenDecimalsCache: cache.NewTokenToDecimals( rf.config.lggr, rf.config.destLP, rf.config.offRamp, - destPriceRegistry, + rf.destPriceRegReader, rf.config.destClient, - int64(offchainConfig.DestFinalityDepth), + int64(rf.config.commitStore.OffchainConfig().DestFinalityDepth), ), + gasPriceEstimator: rf.config.commitStore.GasPriceEstimator(), }, types.ReportingPluginInfo{ Name: "CCIPCommit", @@ -162,11 +179,16 @@ func (r *CommitReportingPlugin) Query(context.Context, types.ReportTimestamp) (t // Observation calculates the sequence number interval ready to be committed and // the token and gas price updates required. A valid report could contain a merkle -// root and/or price updates. +// root and price updates. Price updates should never contain nil values, otherwise +// the observation will be considered invalid and rejected. func (r *CommitReportingPlugin) Observation(ctx context.Context, epochAndRound types.ReportTimestamp, _ types.Query) (types.Observation, error) { lggr := r.lggr.Named("CommitObservation") // If the commit store is down the protocol should halt. - if contractutil.IsCommitStoreDownNow(ctx, lggr, r.config.commitStore) { + down, err := r.commitStoreReader.IsDown(ctx) + if err != nil { + return nil, errors.Wrap(err, "isDown check errored") + } + if down { return nil, ErrCommitStoreIsDown } r.inflightReports.expire(lggr) @@ -197,7 +219,7 @@ func (r *CommitReportingPlugin) Observation(ctx context.Context, epochAndRound t // Even if all values are empty we still want to communicate our observation // with the other nodes, therefore, we always return the observed values. return CommitObservation{ - Interval: commit_store.CommitStoreInterval{ + Interval: ccipdata.CommitStoreInterval{ Min: min, Max: max, }, @@ -206,44 +228,13 @@ func (r *CommitReportingPlugin) Observation(ctx context.Context, epochAndRound t }.Marshal() } -// UpdateLogPollerFilters updates the log poller filters for the source and destination chains. -// pass zeroAddress if destPriceRegistry is unknown, filters with zero address are omitted. -func (rf *CommitReportingPluginFactory) UpdateLogPollerFilters(destPriceRegistry common.Address, qopts ...pg.QOpt) error { - rf.filtersMu.Lock() - defer rf.filtersMu.Unlock() - - // source chain filters - sourceFiltersBefore, sourceFiltersNow := rf.sourceChainFilters, getCommitPluginSourceLpFilters(rf.config.onRampAddress) - created, deleted := logpollerutil.FiltersDiff(sourceFiltersBefore, sourceFiltersNow) - if err := logpollerutil.UnregisterLpFilters(rf.config.sourceLP, deleted, qopts...); err != nil { - return err - } - if err := logpollerutil.RegisterLpFilters(rf.config.sourceLP, created, qopts...); err != nil { - return err - } - rf.sourceChainFilters = sourceFiltersNow - - // destination chain filters - destFiltersBefore, destFiltersNow := rf.destChainFilters, getCommitPluginDestLpFilters(destPriceRegistry, rf.config.offRamp.Address()) - created, deleted = logpollerutil.FiltersDiff(destFiltersBefore, destFiltersNow) - if err := logpollerutil.UnregisterLpFilters(rf.config.destLP, deleted, qopts...); err != nil { - return err - } - if err := logpollerutil.RegisterLpFilters(rf.config.destLP, created, qopts...); err != nil { - return err - } - rf.destChainFilters = destFiltersNow - - return nil -} - func (r *CommitReportingPlugin) calculateMinMaxSequenceNumbers(ctx context.Context, lggr logger.Logger) (uint64, uint64, error) { nextInflightMin, _, err := r.nextMinSeqNum(ctx, lggr) if err != nil { return 0, 0, err } - msgRequests, err := r.config.sourceReader.GetSendRequestsGteSeqNum(ctx, r.config.onRampAddress, nextInflightMin, r.config.checkFinalityTags, int(r.offchainConfig.SourceFinalityDepth)) + msgRequests, err := r.onRampReader.GetSendRequestsGteSeqNum(ctx, nextInflightMin, int(r.offchainConfig.SourceFinalityDepth)) if err != nil { return 0, 0, err } @@ -253,7 +244,7 @@ func (r *CommitReportingPlugin) calculateMinMaxSequenceNumbers(ctx context.Conte } seqNrs := make([]uint64, 0, len(msgRequests)) for _, msgReq := range msgRequests { - seqNrs = append(seqNrs, msgReq.Data.Message.SequenceNumber) + seqNrs = append(seqNrs, msgReq.Data.SequenceNumber) } minSeqNr := seqNrs[0] @@ -270,7 +261,7 @@ func (r *CommitReportingPlugin) calculateMinMaxSequenceNumbers(ctx context.Conte } func (r *CommitReportingPlugin) nextMinSeqNum(ctx context.Context, lggr logger.Logger) (inflightMin, onChainMin uint64, err error) { - nextMinOnChain, err := r.config.commitStore.GetExpectedNextSequenceNumber(&bind.CallOpts{Context: ctx}) + nextMinOnChain, err := r.commitStoreReader.GetExpectedNextSequenceNumber(ctx) if err != nil { return 0, 0, err } @@ -295,13 +286,13 @@ func (r *CommitReportingPlugin) nextMinSeqNum(ctx context.Context, lggr logger.L return mathutil.Max(nextMinOnChain, maxInflight+1), nextMinOnChain, nil } -// All prices are USD ($1=1e18) denominated. We only generate prices we think should be updated; -// otherwise, omitting values means voting to skip updating them +// All prices are USD ($1=1e18) denominated. All prices must be not nil. +// Return token prices should contain the exact same tokens as in tokenDecimals. func (r *CommitReportingPlugin) generatePriceUpdates( ctx context.Context, lggr logger.Logger, tokenDecimals map[common.Address]uint8, -) (sourceGasPriceUSD *big.Int, tokenPricesUSD map[common.Address]*big.Int, err error) { +) (sourceGasPriceUSD prices.GasPrice, tokenPricesUSD map[common.Address]*big.Int, err error) { tokensWithDecimal := make([]common.Address, 0, len(tokenDecimals)) for token := range tokenDecimals { tokensWithDecimal = append(tokensWithDecimal, token) @@ -309,10 +300,10 @@ func (r *CommitReportingPlugin) generatePriceUpdates( // Include wrapped native in our token query as way to identify the source native USD price. // notice USD is in 1e18 scale, i.e. $1 = 1e18 - queryTokens := append([]common.Address{r.config.sourceNative}, tokensWithDecimal...) + queryTokens := append([]common.Address{r.sourceNative}, tokensWithDecimal...) sort.Slice(queryTokens, func(i, j int) bool { return queryTokens[i].String() < queryTokens[j].String() }) // make the query deterministic - rawTokenPricesUSD, err := r.config.priceGetter.TokenPricesUSD(ctx, queryTokens) + rawTokenPricesUSD, err := r.priceGetter.TokenPricesUSD(ctx, queryTokens) if err != nil { return nil, nil, err } @@ -325,9 +316,9 @@ func (r *CommitReportingPlugin) generatePriceUpdates( } } - sourceNativePriceUSD, exists := rawTokenPricesUSD[r.config.sourceNative] + sourceNativePriceUSD, exists := rawTokenPricesUSD[r.sourceNative] if !exists { - return nil, nil, fmt.Errorf("missing source native (%s) price", r.config.sourceNative) + return nil, nil, fmt.Errorf("missing source native (%s) price", r.sourceNative) } tokenPricesUSD = make(map[common.Address]*big.Int, len(rawTokenPricesUSD)) @@ -341,22 +332,19 @@ func (r *CommitReportingPlugin) generatePriceUpdates( tokenPricesUSD[token] = calculateUsdPer1e18TokenAmount(rawTokenPricesUSD[token], decimals) } - // Observe a source chain price for pricing. - sourceGasPriceWei, _, err := r.config.sourceFeeEstimator.GetFee(ctx, nil, 0, assets.NewWei(big.NewInt(int64(r.offchainConfig.MaxGasPrice)))) + sourceGasPrice, err := r.gasPriceEstimator.GetGasPrice(ctx) if err != nil { return nil, nil, err } - // Use legacy if no dynamic is available. - gasPrice := sourceGasPriceWei.Legacy.ToInt() - if sourceGasPriceWei.DynamicFeeCap != nil { - gasPrice = sourceGasPriceWei.DynamicFeeCap.ToInt() + if sourceGasPrice == nil { + return nil, nil, errors.Errorf("missing gas price") } - if gasPrice == nil { - return nil, nil, fmt.Errorf("missing gas price %+v", sourceGasPriceWei) + sourceGasPriceUSD, err = r.gasPriceEstimator.DenoteInUSD(sourceGasPrice, sourceNativePriceUSD) + if err != nil { + return nil, nil, err } - sourceGasPriceUSD = ccipcalc.CalculateUsdPerUnitGas(gasPrice, sourceNativePriceUSD) - lggr.Infow("Observing gas price", "observedGasPriceWei", gasPrice, "observedGasPriceUSD", sourceGasPriceUSD) + lggr.Infow("Observing gas price", "observedGasPriceWei", sourceGasPrice, "observedGasPriceUSD", sourceGasPriceUSD) lggr.Infow("Observing token prices", "tokenPrices", tokenPricesUSD, "sourceNativePriceUSD", sourceNativePriceUSD) return sourceGasPriceUSD, tokenPricesUSD, nil } @@ -372,10 +360,9 @@ func calculateUsdPer1e18TokenAmount(price *big.Int, decimals uint8) *big.Int { // Gets the latest token price updates based on logs within the heartbeat // The updates returned by this function are guaranteed to not contain nil values. func (r *CommitReportingPlugin) getLatestTokenPriceUpdates(ctx context.Context, now time.Time, checkInflight bool) (map[common.Address]update, error) { - tokenPriceUpdates, err := r.config.destReader.GetTokenPriceUpdatesCreatedAfter( + tokenPriceUpdates, err := r.destPriceRegistryReader.GetTokenPriceUpdatesCreatedAfter( ctx, - r.destPriceRegistry.Address(), - now.Add(-r.offchainConfig.FeeUpdateHeartBeat.Duration()), + now.Add(-r.offchainConfig.TokenPriceHeartBeat), 0, ) if err != nil { @@ -383,8 +370,8 @@ func (r *CommitReportingPlugin) getLatestTokenPriceUpdates(ctx context.Context, } latestUpdates := make(map[common.Address]update) - for _, tokenPriceUpdate := range tokenPriceUpdates { - priceUpdate := tokenPriceUpdate.Data + for _, tokenUpdate := range tokenPriceUpdates { + priceUpdate := tokenUpdate.Data // Ordered by ascending timestamps timestamp := time.Unix(priceUpdate.Timestamp.Int64(), 0) if priceUpdate.Value != nil && !timestamp.Before(latestUpdates[priceUpdate.Token].timestamp) { @@ -411,28 +398,26 @@ func (r *CommitReportingPlugin) getLatestTokenPriceUpdates(ctx context.Context, return latestUpdates, nil } -// Gets the latest gas price updates based on logs within the heartbeat -func (r *CommitReportingPlugin) getLatestGasPriceUpdate(ctx context.Context, now time.Time, checkInflight bool) (gasPriceUpdate update, error error) { +// getLatestGasPriceUpdate returns the latest gas price update based on logs within the heartbeat. +// If an update is found, it is not expected to contain a nil value. If no updates found, empty update with nil value is returned. +func (r *CommitReportingPlugin) getLatestGasPriceUpdate(ctx context.Context, now time.Time, checkInflight bool) (gasUpdate update, error error) { if checkInflight { - latestInflightGasPriceUpdate := r.inflightReports.getLatestInflightGasPriceUpdate() - if latestInflightGasPriceUpdate != nil && latestInflightGasPriceUpdate.timestamp.After(gasPriceUpdate.timestamp) { - gasPriceUpdate = *latestInflightGasPriceUpdate - } + latestInflightGasPriceUpdates := r.inflightReports.latestInflightGasPriceUpdates() + if inflightUpdate, exists := latestInflightGasPriceUpdates[r.sourceChainSelector]; exists { + gasUpdate = inflightUpdate + r.lggr.Infow("Latest gas price from inflight", "gasPriceUpdateVal", gasUpdate.value, "gasPriceUpdateTs", gasUpdate.timestamp) - if gasPriceUpdate.value != nil { - r.lggr.Infow("Latest gas price from inflight", "gasPriceUpdateVal", gasPriceUpdate.value, "gasPriceUpdateTs", gasPriceUpdate.timestamp) // Gas price can fluctuate frequently, many updates may be in flight. // If there is gas price update inflight, use it as source of truth, no need to check onchain. - return gasPriceUpdate, nil + return gasUpdate, nil } } // If there are no price updates inflight, check latest prices onchain - gasPriceUpdates, err := r.config.destReader.GetGasPriceUpdatesCreatedAfter( + gasPriceUpdates, err := r.destPriceRegistryReader.GetGasPriceUpdatesCreatedAfter( ctx, - r.destPriceRegistry.Address(), - r.config.sourceChainSelector, - now.Add(-r.offchainConfig.FeeUpdateHeartBeat.Duration()), + r.sourceChainSelector, + now.Add(-r.offchainConfig.GasPriceHeartBeat), 0, ) if err != nil { @@ -442,27 +427,37 @@ func (r *CommitReportingPlugin) getLatestGasPriceUpdate(ctx context.Context, now for _, priceUpdate := range gasPriceUpdates { // Ordered by ascending timestamps timestamp := time.Unix(priceUpdate.Data.Timestamp.Int64(), 0) - if !timestamp.Before(gasPriceUpdate.timestamp) { - gasPriceUpdate = update{ + if !timestamp.Before(gasUpdate.timestamp) { + gasUpdate = update{ timestamp: timestamp, value: priceUpdate.Data.Value, } } } - if gasPriceUpdate.value != nil { - r.lggr.Infow("Latest gas price from log poller", "gasPriceUpdateVal", gasPriceUpdate.value, "gasPriceUpdateTs", gasPriceUpdate.timestamp) - } - - return gasPriceUpdate, nil + r.lggr.Infow("Latest gas price from log poller", "gasPriceUpdateVal", gasUpdate.value, "gasPriceUpdateTs", gasUpdate.timestamp) + return gasUpdate, nil } func (r *CommitReportingPlugin) Report(ctx context.Context, epochAndRound types.ReportTimestamp, _ types.Query, observations []types.AttributedObservation) (bool, types.Report, error) { now := time.Now() lggr := r.lggr.Named("CommitReport") parsableObservations := getParsableObservations[CommitObservation](lggr, observations) - var intervals []commit_store.CommitStoreInterval - for _, obs := range parsableObservations { + + // tokens in the tokenDecimalsCache represent supported tokens on the dest chain + supportedTokensMap, err := r.tokenDecimalsCache.Get(ctx) + if err != nil { + return false, nil, err + } + + // Filters out parsable but faulty observations + validObservations, err := validateObservations(ctx, lggr, supportedTokensMap, r.F, parsableObservations) + if err != nil { + return false, nil, err + } + + var intervals []ccipdata.CommitStoreInterval + for _, obs := range validObservations { intervals = append(intervals, obs.Interval) } @@ -481,18 +476,21 @@ func (r *CommitReportingPlugin) Report(ctx context.Context, epochAndRound types. return false, nil, err } - priceUpdates := r.calculatePriceUpdates(parsableObservations, latestGasPrice, latestTokenPrices) + tokenPrices, gasPrices, err := r.calculatePriceUpdates(validObservations, latestGasPrice, latestTokenPrices) + if err != nil { + return false, nil, err + } // If there are no fee updates and the interval is zero there is no report to produce. - if len(priceUpdates.TokenPriceUpdates) == 0 && priceUpdates.DestChainSelector == 0 && agreedInterval.Min == 0 { + if len(tokenPrices) == 0 && len(gasPrices) == 0 && agreedInterval.Max == 0 { lggr.Infow("Empty report, skipping") return false, nil, nil } - report, err := r.buildReport(ctx, lggr, agreedInterval, priceUpdates) + report, err := r.buildReport(ctx, lggr, agreedInterval, gasPrices, tokenPrices) if err != nil { return false, nil, err } - encodedReport, err := abihelpers.EncodeCommitReport(report) + encodedReport, err := r.commitStoreReader.EncodeCommitReport(report) if err != nil { return false, nil, err } @@ -500,14 +498,57 @@ func (r *CommitReportingPlugin) Report(ctx context.Context, epochAndRound types. "merkleRoot", hex.EncodeToString(report.MerkleRoot[:]), "minSeqNr", report.Interval.Min, "maxSeqNr", report.Interval.Max, - "tokenPriceUpdates", report.PriceUpdates.TokenPriceUpdates, - "destChainSelector", report.PriceUpdates.DestChainSelector, - "sourceUsdPerUnitGas", report.PriceUpdates.UsdPerUnitGas, + "tokenPriceUpdates", report.TokenPrices, + "gasPriceUpdates", report.GasPrices, "epochAndRound", epochAndRound, ) return true, encodedReport, nil } +// validateObservations validates the given observations. +// An observation is rejected if any of its gas price or token price is nil. With current CommitObservation implementation, prices +// are checked to ensure no nil values before adding to Observation, hence an observation that contains nil values comes from a faulty node. +func validateObservations(ctx context.Context, lggr logger.Logger, supportedTokensMap map[common.Address]uint8, f int, observations []CommitObservation) (validObs []CommitObservation, err error) { + for _, obs := range observations { + // If gas price is reported as nil, the observation is faulty, skip the observation. + if obs.SourceGasPriceUSD == nil { + lggr.Warnw("Skipping observation due to nil SourceGasPriceUSD") + continue + } + // If observed number of token prices does not match number of supported tokens on dest chain, skip the observation. + if len(supportedTokensMap) != len(obs.TokenPricesUSD) { + lggr.Warnw("Skipping observation due to token count mismatch", "expecting", len(supportedTokensMap), "got", len(obs.TokenPricesUSD)) + continue + } + // If any of the observed token prices is reported as nil, or not supported on dest chain, the observation is faulty, skip the observation. + // Printing all faulty prices instead of short-circuiting to make log more informative. + skipObservation := false + for token, price := range obs.TokenPricesUSD { + if price == nil { + lggr.Warnw("Nil value in observed TokenPricesUSD", "token", token.Hex()) + skipObservation = true + } + if _, exists := supportedTokensMap[token]; !exists { + lggr.Warnw("Unsupported token in observed TokenPricesUSD", "token", token.Hex()) + skipObservation = true + } + } + if skipObservation { + lggr.Warnw("Skipping observation due to invalid TokenPricesUSD") + continue + } + + validObs = append(validObs, obs) + } + + // We require at least f+1 valid observations. This corresponds to the scenario where f of the 2f+1 are faulty. + if len(validObs) <= f { + return nil, errors.Errorf("Not enough valid observations to form consensus: #obs=%d, f=%d", len(validObs), f) + } + + return validObs, nil +} + // calculateIntervalConsensus compresses a set of intervals into one interval // taking into account f which is the maximum number of faults across the whole DON. // OCR itself won't call Report unless there are 2*f+1 observations @@ -516,13 +557,7 @@ func (r *CommitReportingPlugin) Report(ctx context.Context, epochAndRound types. // we'll either have f+1 parsed honest values here, 2f+1 parsed values with f adversarial values or somewhere // in between. // rangeLimit is the maximum range of the interval. If the interval is larger than this, it will be truncated. Zero means no limit. -func calculateIntervalConsensus(intervals []commit_store.CommitStoreInterval, f int, rangeLimit uint64) (commit_store.CommitStoreInterval, error) { - // We require at least f+1 parsed values. This corresponds to the scenario where f of the 2f+1 are faulty - // in the sense that they are unparseable. - if len(intervals) <= f { - return commit_store.CommitStoreInterval{}, errors.Errorf("Not enough intervals to form consensus: #obs=%d, f=%d", len(intervals), f) - } - +func calculateIntervalConsensus(intervals []ccipdata.CommitStoreInterval, f int, rangeLimit uint64) (ccipdata.CommitStoreInterval, error) { // To understand min/max selection here, we need to consider an adversary that controls f values // and is intentionally trying to stall the protocol or influence the value returned. For simplicity // consider f=1 and n=4 nodes. In that case adversary may try to bias the min or max high/low. @@ -542,7 +577,7 @@ func calculateIntervalConsensus(intervals []commit_store.CommitStoreInterval, f // The only way a report could have a minSeqNum of 0 is when there are no messages to report // and the report is potentially still valid for gas fee updates. if minSeqNum == 0 { - return commit_store.CommitStoreInterval{Min: 0, Max: 0}, nil + return ccipdata.CommitStoreInterval{Min: 0, Max: 0}, nil } // Consider a similar example to the sorted_mins one above except where they are maxes. // We choose the more "conservative" sorted_maxes[f] so: @@ -561,7 +596,7 @@ func calculateIntervalConsensus(intervals []commit_store.CommitStoreInterval, f if maxSeqNum < minSeqNum { // If the consensus report is invalid for onchain acceptance, we do not vote for it as // an early termination step. - return commit_store.CommitStoreInterval{}, errors.New("max seq num smaller than min") + return ccipdata.CommitStoreInterval{}, errors.New("max seq num smaller than min") } // If the range is too large, truncate it. @@ -569,7 +604,7 @@ func calculateIntervalConsensus(intervals []commit_store.CommitStoreInterval, f maxSeqNum = minSeqNum + rangeLimit - 1 } - return commit_store.CommitStoreInterval{ + return ccipdata.CommitStoreInterval{ Min: minSeqNum, Max: maxSeqNum, }, nil @@ -577,36 +612,26 @@ func calculateIntervalConsensus(intervals []commit_store.CommitStoreInterval, f // Note priceUpdates must be deterministic. // The provided latestTokenPrices should not contain nil values. -func (r *CommitReportingPlugin) calculatePriceUpdates(observations []CommitObservation, latestGasPrice update, latestTokenPrices map[common.Address]update) commit_store.InternalPriceUpdates { +func (r *CommitReportingPlugin) calculatePriceUpdates(observations []CommitObservation, latestGasPrice update, latestTokenPrices map[common.Address]update) ([]ccipdata.TokenPrice, []ccipdata.GasPrice, error) { priceObservations := make(map[common.Address][]*big.Int) - var sourceGasObservations []*big.Int + var sourceGasObservations []prices.GasPrice for _, obs := range observations { - if obs.SourceGasPriceUSD != nil { - // Add only non-nil source gas price - sourceGasObservations = append(sourceGasObservations, obs.SourceGasPriceUSD) - } + sourceGasObservations = append(sourceGasObservations, obs.SourceGasPriceUSD) // iterate over any token which price is included in observations for token, price := range obs.TokenPricesUSD { - if price == nil { - continue - } priceObservations[token] = append(priceObservations[token], price) } } - var tokenPriceUpdates []commit_store.InternalTokenPriceUpdate + var tokenPriceUpdates []ccipdata.TokenPrice for token, tokenPriceObservations := range priceObservations { - // If majority report a token price, include it in the update - if len(tokenPriceObservations) <= r.F { - continue - } medianPrice := ccipcalc.BigIntMedian(tokenPriceObservations) latestTokenPrice, exists := latestTokenPrices[token] if exists { - tokenPriceUpdatedRecently := time.Since(latestTokenPrice.timestamp) < r.offchainConfig.FeeUpdateHeartBeat.Duration() - tokenPriceNotChanged := !ccipcalc.Deviates(medianPrice, latestTokenPrice.value, int64(r.offchainConfig.FeeUpdateDeviationPPB)) + tokenPriceUpdatedRecently := time.Since(latestTokenPrice.timestamp) < r.offchainConfig.TokenPriceHeartBeat + tokenPriceNotChanged := !ccipcalc.Deviates(medianPrice, latestTokenPrice.value, int64(r.offchainConfig.TokenPriceDeviationPPB)) if tokenPriceUpdatedRecently && tokenPriceNotChanged { r.lggr.Debugw("price was updated recently, skipping the update", "token", token, "newPrice", medianPrice, "existingPrice", latestTokenPrice.value) @@ -614,105 +639,112 @@ func (r *CommitReportingPlugin) calculatePriceUpdates(observations []CommitObser } } - tokenPriceUpdates = append(tokenPriceUpdates, commit_store.InternalTokenPriceUpdate{ - SourceToken: token, - UsdPerToken: medianPrice, + tokenPriceUpdates = append(tokenPriceUpdates, ccipdata.TokenPrice{ + Token: token, + Value: medianPrice, }) } // Determinism required. sort.Slice(tokenPriceUpdates, func(i, j int) bool { - return bytes.Compare(tokenPriceUpdates[i].SourceToken[:], tokenPriceUpdates[j].SourceToken[:]) == -1 + return bytes.Compare(tokenPriceUpdates[i].Token[:], tokenPriceUpdates[j].Token[:]) == -1 }) - usdPerUnitGas := big.NewInt(0) - destChainSelector := uint64(0) - - if len(sourceGasObservations) > r.F { - usdPerUnitGas = ccipcalc.BigIntMedian(sourceGasObservations) // Compute the median price - destChainSelector = r.config.sourceChainSelector // Assuming plugin lane is A->B, we write to B the gas price of A + newGasPrice, err := r.gasPriceEstimator.Median(sourceGasObservations) // Compute the median price + if err != nil { + return nil, nil, err + } + destChainSelector := r.sourceChainSelector // Assuming plugin lane is A->B, we write to B the gas price of A - if latestGasPrice.value != nil { - gasPriceUpdatedRecently := time.Since(latestGasPrice.timestamp) < r.offchainConfig.FeeUpdateHeartBeat.Duration() - gasPriceNotChanged := !ccipcalc.Deviates(usdPerUnitGas, latestGasPrice.value, int64(r.offchainConfig.FeeUpdateDeviationPPB)) - if gasPriceUpdatedRecently && gasPriceNotChanged { - usdPerUnitGas = big.NewInt(0) - destChainSelector = uint64(0) - } + var gasPrices []ccipdata.GasPrice + // Default to updating so that we update if there are no prior updates. + shouldUpdate := true + if latestGasPrice.value != nil { + gasPriceUpdatedRecently := time.Since(latestGasPrice.timestamp) < r.offchainConfig.GasPriceHeartBeat + gasPriceDeviated, err := r.gasPriceEstimator.Deviates(newGasPrice, latestGasPrice.value) + if err != nil { + return nil, nil, err + } + if gasPriceUpdatedRecently && !gasPriceDeviated { + shouldUpdate = false } } - - return commit_store.InternalPriceUpdates{ - TokenPriceUpdates: tokenPriceUpdates, - DestChainSelector: destChainSelector, - UsdPerUnitGas: usdPerUnitGas, // we MUST pass zero to skip the update (never nil) + if shouldUpdate { + // Although onchain interface accepts multi gas updates, we only do 1 gas price per report for now. + gasPrices = append(gasPrices, ccipdata.GasPrice{DestChainSelector: destChainSelector, Value: newGasPrice}) } + + return tokenPriceUpdates, gasPrices, nil } // buildReport assumes there is at least one message in reqs. -func (r *CommitReportingPlugin) buildReport(ctx context.Context, lggr logger.Logger, interval commit_store.CommitStoreInterval, priceUpdates commit_store.InternalPriceUpdates) (commit_store.CommitStoreCommitReport, error) { +func (r *CommitReportingPlugin) buildReport(ctx context.Context, lggr logger.Logger, interval ccipdata.CommitStoreInterval, gasPrices []ccipdata.GasPrice, tokenPrices []ccipdata.TokenPrice) (ccipdata.CommitStoreReport, error) { // If no messages are needed only include fee updates if interval.Min == 0 { - return commit_store.CommitStoreCommitReport{ - PriceUpdates: priceUpdates, - MerkleRoot: [32]byte{}, - Interval: interval, + return ccipdata.CommitStoreReport{ + TokenPrices: tokenPrices, + GasPrices: gasPrices, + MerkleRoot: [32]byte{}, + Interval: interval, }, nil } // Logs are guaranteed to be in order of seq num, since these are finalized logs only // and the contract's seq num is auto-incrementing. - sendRequests, err := r.config.sourceReader.GetSendRequestsBetweenSeqNums( + sendRequests, err := r.onRampReader.GetSendRequestsBetweenSeqNums( ctx, - r.config.onRampAddress, interval.Min, interval.Max, int(r.offchainConfig.SourceFinalityDepth), ) if err != nil { - return commit_store.CommitStoreCommitReport{}, err - } - - leaves, err := hashlib.LeavesFromIntervals(lggr, interval, r.config.leafHasher, sendRequests) - if err != nil { - return commit_store.CommitStoreCommitReport{}, err + return ccipdata.CommitStoreReport{}, err } - - if len(leaves) == 0 { - lggr.Warn("No leaves found in interval", + if len(sendRequests) == 0 { + lggr.Warn("No messages found in interval", "minSeqNr", interval.Min, "maxSeqNr", interval.Max) - return commit_store.CommitStoreCommitReport{}, fmt.Errorf("tried building a tree without leaves") + return ccipdata.CommitStoreReport{}, fmt.Errorf("tried building a tree without leaves") } + leaves := make([][32]byte, 0, len(sendRequests)) + var seqNrs []uint64 + for _, req := range sendRequests { + leaves = append(leaves, req.Data.Hash) + seqNrs = append(seqNrs, req.Data.SequenceNumber) + } + if !ccipcalc.ContiguousReqs(lggr, interval.Min, interval.Max, seqNrs) { + return ccipdata.CommitStoreReport{}, errors.Errorf("do not have full range [%v, %v] have %v", interval.Min, interval.Max, seqNrs) + } tree, err := merklemulti.NewTree(hashlib.NewKeccakCtx(), leaves) if err != nil { - return commit_store.CommitStoreCommitReport{}, err + return ccipdata.CommitStoreReport{}, err } - return commit_store.CommitStoreCommitReport{ - PriceUpdates: priceUpdates, - MerkleRoot: tree.Root(), - Interval: interval, + return ccipdata.CommitStoreReport{ + GasPrices: gasPrices, + TokenPrices: tokenPrices, + MerkleRoot: tree.Root(), + Interval: interval, }, nil } func (r *CommitReportingPlugin) ShouldAcceptFinalizedReport(ctx context.Context, reportTimestamp types.ReportTimestamp, report types.Report) (bool, error) { - parsedReport, err := abihelpers.DecodeCommitReport(report) + parsedReport, err := r.commitStoreReader.DecodeCommitReport(report) if err != nil { return false, err } + lggr := r.lggr.Named("CommitShouldAcceptFinalizedReport").With( "merkleRoot", parsedReport.MerkleRoot, "minSeqNum", parsedReport.Interval.Min, "maxSeqNum", parsedReport.Interval.Max, - "destChainSelector", parsedReport.PriceUpdates.DestChainSelector, - "usdPerUnitGas", parsedReport.PriceUpdates.UsdPerUnitGas, - "tokenPriceUpdates", parsedReport.PriceUpdates.TokenPriceUpdates, + "gasPriceUpdates", parsedReport.GasPrices, + "tokenPriceUpdates", parsedReport.TokenPrices, "reportTimestamp", reportTimestamp, ) // Empty report, should not be put on chain - if parsedReport.MerkleRoot == [32]byte{} && parsedReport.PriceUpdates.DestChainSelector == 0 && len(parsedReport.PriceUpdates.TokenPriceUpdates) == 0 { + if parsedReport.MerkleRoot == [32]byte{} && len(parsedReport.GasPrices) == 0 && len(parsedReport.TokenPrices) == 0 { lggr.Warn("Empty report, should not be put on chain") return false, nil } @@ -733,7 +765,7 @@ func (r *CommitReportingPlugin) ShouldAcceptFinalizedReport(ctx context.Context, // ShouldTransmitAcceptedReport checks if the report is stale, if it is it should not be transmitted. func (r *CommitReportingPlugin) ShouldTransmitAcceptedReport(ctx context.Context, reportTimestamp types.ReportTimestamp, report types.Report) (bool, error) { lggr := r.lggr.Named("CommitShouldTransmitAcceptedReport") - parsedReport, err := abihelpers.DecodeCommitReport(report) + parsedReport, err := r.commitStoreReader.DecodeCommitReport(report) if err != nil { return false, err } @@ -761,31 +793,36 @@ func (r *CommitReportingPlugin) ShouldTransmitAcceptedReport(ctx context.Context // If there is no merkle root but there is a gas update, only this gas update is used for staleness checks. // If only price updates are included, the price updates are used to check for staleness // If nothing is included the report is always considered stale. -func (r *CommitReportingPlugin) isStaleReport(ctx context.Context, lggr logger.Logger, report commit_store.CommitStoreCommitReport, checkInflight bool, reportTimestamp types.ReportTimestamp) bool { +func (r *CommitReportingPlugin) isStaleReport(ctx context.Context, lggr logger.Logger, report ccipdata.CommitStoreReport, checkInflight bool, reportTimestamp types.ReportTimestamp) bool { // If there is a merkle root, ignore all other staleness checks and only check for sequence number staleness if report.MerkleRoot != [32]byte{} { return r.isStaleMerkleRoot(ctx, lggr, report.Interval, checkInflight) } - hasGasPriceUpdate := report.PriceUpdates.DestChainSelector != 0 - hasTokenPriceUpdates := len(report.PriceUpdates.TokenPriceUpdates) > 0 + hasGasPriceUpdate := len(report.GasPrices) > 0 + hasTokenPriceUpdates := len(report.TokenPrices) > 0 // If there is no merkle root, no gas price update and no token price update // we don't want to write anything on-chain, so we consider this report stale. if !hasGasPriceUpdate && !hasTokenPriceUpdates { return true } + // Commit plugin currently only supports 1 gas price per report. If report contains more than 1, reject the report. + if len(report.GasPrices) > 1 { + lggr.Errorw("Report is stale because it contains more than 1 gas price update", "GasPriceUpdates", report.GasPrices) + return true + } // We consider a price update as stale when, there isn't an update or there is an update that is stale. - gasPriceStale := !hasGasPriceUpdate || r.isStaleGasPrice(ctx, lggr, report.PriceUpdates, checkInflight) - tokenPricesStale := !hasTokenPriceUpdates || r.isStaleTokenPrices(ctx, lggr, report.PriceUpdates.TokenPriceUpdates, checkInflight) + gasPriceStale := !hasGasPriceUpdate || r.isStaleGasPrice(ctx, lggr, report.GasPrices[0], checkInflight) + tokenPricesStale := !hasTokenPriceUpdates || r.isStaleTokenPrices(ctx, lggr, report.TokenPrices, checkInflight) if gasPriceStale && tokenPricesStale { return true } // If report only has price update, check if its epoch and round lags behind the latest onchain - lastPriceEpochAndRound, err := r.config.commitStore.GetLatestPriceEpochAndRound(&bind.CallOpts{Context: ctx}) + lastPriceEpochAndRound, err := r.commitStoreReader.GetLatestPriceEpochAndRound(ctx) if err != nil { // Assume it's a transient issue getting the last report and try again on the next round return true @@ -795,7 +832,7 @@ func (r *CommitReportingPlugin) isStaleReport(ctx context.Context, lggr logger.L return lastPriceEpochAndRound >= thisEpochAndRound } -func (r *CommitReportingPlugin) isStaleMerkleRoot(ctx context.Context, lggr logger.Logger, reportInterval commit_store.CommitStoreInterval, checkInflight bool) bool { +func (r *CommitReportingPlugin) isStaleMerkleRoot(ctx context.Context, lggr logger.Logger, reportInterval ccipdata.CommitStoreInterval, checkInflight bool) bool { nextInflightMin, nextOnChainMin, err := r.nextMinSeqNum(ctx, lggr) if err != nil { // Assume it's a transient issue getting the last report and try again on the next round @@ -803,7 +840,7 @@ func (r *CommitReportingPlugin) isStaleMerkleRoot(ctx context.Context, lggr logg } if checkInflight && nextInflightMin != reportInterval.Min { - // There are sequence numbers missing between the commitStore/inflight txs and the proposed report. + // There are sequence numbers missing between the commitStoreReader/inflight txs and the proposed report. // The report will fail onchain unless the inflight cache is in an incorrect state. A state like this // could happen for various reasons, e.g. a reboot of the node emptying the caches, and should be self-healing. // We do not submit a tx and wait for the protocol to self-heal by updating the caches or invalidating @@ -822,24 +859,33 @@ func (r *CommitReportingPlugin) isStaleMerkleRoot(ctx context.Context, lggr logg return false } -func (r *CommitReportingPlugin) isStaleGasPrice(ctx context.Context, lggr logger.Logger, priceUpdates commit_store.InternalPriceUpdates, checkInflight bool) bool { - gasPriceUpdate, err := r.getLatestGasPriceUpdate(ctx, time.Now(), checkInflight) +func (r *CommitReportingPlugin) isStaleGasPrice(ctx context.Context, lggr logger.Logger, gasPrice ccipdata.GasPrice, checkInflight bool) bool { + latestGasPrice, err := r.getLatestGasPriceUpdate(ctx, time.Now(), checkInflight) if err != nil { + lggr.Errorw("Report is stale because getLatestGasPriceUpdate failed", "err", err) return true } - if gasPriceUpdate.value != nil && !ccipcalc.Deviates(priceUpdates.UsdPerUnitGas, gasPriceUpdate.value, int64(r.offchainConfig.FeeUpdateDeviationPPB)) { - lggr.Infow("Report is stale because of gas price", - "latestGasPriceUpdate", gasPriceUpdate.value, - "usdPerUnitGas", priceUpdates.UsdPerUnitGas, - "destChainSelector", priceUpdates.DestChainSelector) - return true + if latestGasPrice.value != nil { + gasPriceDeviated, err := r.gasPriceEstimator.Deviates(gasPrice.Value, latestGasPrice.value) + if err != nil { + lggr.Errorw("Report is stale because deviation check failed", "err", err) + return true + } + + if !gasPriceDeviated { + lggr.Infow("Report is stale because of gas price", + "latestGasPriceUpdate", latestGasPrice.value, + "currentUsdPerUnitGas", gasPrice.Value, + "destChainSelector", gasPrice.DestChainSelector) + return true + } } return false } -func (r *CommitReportingPlugin) isStaleTokenPrices(ctx context.Context, lggr logger.Logger, priceUpdates []commit_store.InternalTokenPriceUpdate, checkInflight bool) bool { +func (r *CommitReportingPlugin) isStaleTokenPrices(ctx context.Context, lggr logger.Logger, priceUpdates []ccipdata.TokenPrice, checkInflight bool) bool { // getting the last price updates without including inflight is like querying // current prices onchain, but uses logpoller's data to save on the RPC requests latestTokenPriceUpdates, err := r.getLatestTokenPriceUpdates(ctx, time.Now(), checkInflight) @@ -848,14 +894,14 @@ func (r *CommitReportingPlugin) isStaleTokenPrices(ctx context.Context, lggr log } for _, tokenUpdate := range priceUpdates { - latestUpdate, ok := latestTokenPriceUpdates[tokenUpdate.SourceToken] - priceEqual := ok && !ccipcalc.Deviates(tokenUpdate.UsdPerToken, latestUpdate.value, int64(r.offchainConfig.FeeUpdateDeviationPPB)) + latestUpdate, ok := latestTokenPriceUpdates[tokenUpdate.Token] + priceEqual := ok && !ccipcalc.Deviates(tokenUpdate.Value, latestUpdate.value, int64(r.offchainConfig.TokenPriceDeviationPPB)) if !priceEqual { - lggr.Infow("Found non-stale token price", "token", tokenUpdate.SourceToken, "usdPerToken", tokenUpdate.UsdPerToken, "latestUpdate", latestUpdate.value) + lggr.Infow("Found non-stale token price", "token", tokenUpdate.Token, "usdPerToken", tokenUpdate.Value, "latestUpdate", latestUpdate.value) return false } - lggr.Infow("Token price is stale", "latestTokenPrice", latestUpdate.value, "usdPerToken", tokenUpdate.UsdPerToken, "token", tokenUpdate.SourceToken) + lggr.Infow("Token price is stale", "latestTokenPrice", latestUpdate.value, "usdPerToken", tokenUpdate.Value, "token", tokenUpdate.Token) } lggr.Infow("All token prices are stale") diff --git a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go index 8d7e0ab51b..d47d2bd123 100644 --- a/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/commit_reporting_plugin_test.go @@ -2,6 +2,7 @@ package ccip import ( "context" + "encoding/json" "fmt" "math/big" "math/rand" @@ -10,36 +11,32 @@ import ( "testing" "time" - gethtypes "github.com/ethereum/go-ethereum/core/types" - + "github.com/Masterminds/semver/v3" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/leanovate/gopter" "github.com/leanovate/gopter/gen" "github.com/leanovate/gopter/prop" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/chainlink/v2/core/assets" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + mocks2 "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/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/merklemulti" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/pricegetter" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" - + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -54,7 +51,7 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { commitStoreIsPaused bool commitStoreSeqNum uint64 tokenPrices map[common.Address]*big.Int - sendReqs []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested] + sendReqs []ccipdata.Event[internal.EVM2EVMMessage] tokenDecimals map[common.Address]uint8 fee *big.Int @@ -68,9 +65,9 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { someTokenAddr: big.NewInt(2), sourceNativeTokenAddr: big.NewInt(2), }, - sendReqs: []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{ - {Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{Message: evm_2_evm_onramp.InternalEVM2EVMMessage{SequenceNumber: 54}}}, - {Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{Message: evm_2_evm_onramp.InternalEVM2EVMMessage{SequenceNumber: 55}}}, + sendReqs: []ccipdata.Event[internal.EVM2EVMMessage]{ + {Data: internal.EVM2EVMMessage{SequenceNumber: 54}}, + {Data: internal.EVM2EVMMessage{SequenceNumber: 55}}, }, fee: big.NewInt(100), tokenDecimals: map[common.Address]uint8{ @@ -81,7 +78,7 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { someTokenAddr: big.NewInt(20000000000), }, SourceGasPriceUSD: big.NewInt(0), - Interval: commit_store.CommitStoreInterval{ + Interval: ccipdata.CommitStoreInterval{ Min: 54, Max: 55, }, @@ -97,15 +94,17 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { ctx := testutils.Context(t) for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - onRampAddress := utils.RandomAddress() sourceFinalityDepth := 10 - commitStore, _ := testhelpers.NewFakeCommitStore(t, tc.commitStoreSeqNum) - commitStore.SetPaused(tc.commitStoreIsPaused) + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + commitStoreReader.On("IsDown", ctx).Return(tc.commitStoreIsPaused, nil) + if !tc.commitStoreIsPaused { + commitStoreReader.On("GetExpectedNextSequenceNumber", ctx).Return(tc.commitStoreSeqNum, nil) + } - sourceReader := ccipdata.NewMockReader(t) + onRampReader := ccipdata.NewMockOnRampReader(t) if len(tc.sendReqs) > 0 { - sourceReader.On("GetSendRequestsGteSeqNum", ctx, onRampAddress, tc.commitStoreSeqNum, false, sourceFinalityDepth). + onRampReader.On("GetSendRequestsGteSeqNum", ctx, tc.commitStoreSeqNum, sourceFinalityDepth). Return(tc.sendReqs, nil) } @@ -123,23 +122,24 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { priceGet.On("TokenPricesUSD", mock.Anything, addrs).Return(tc.tokenPrices, nil) } - sourceFeeEst := mocks.NewEvmFeeEstimator(t) + gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) if tc.fee != nil { - sourceFeeEst.On("GetFee", ctx, []byte(nil), uint32(0), assets.NewWei(big.NewInt(0))). - Return(gas.EvmFee{Legacy: assets.NewWei(tc.fee)}, uint32(0), nil) + var p prices.GasPrice = tc.fee + var pUSD prices.GasPrice = ccipcalc.CalculateUsdPerUnitGas(p, tc.tokenPrices[sourceNativeTokenAddr]) + gasPriceEstimator.On("GetGasPrice", ctx).Return(p, nil) + gasPriceEstimator.On("DenoteInUSD", p, tc.tokenPrices[sourceNativeTokenAddr]).Return(pUSD, nil) } p := &CommitReportingPlugin{} p.lggr = logger.TestLogger(t) p.inflightReports = newInflightCommitReportsContainer(time.Hour) - p.config.commitStore = commitStore - p.config.onRampAddress = onRampAddress + p.commitStoreReader = commitStoreReader p.offchainConfig.SourceFinalityDepth = uint32(sourceFinalityDepth) - p.config.sourceReader = sourceReader + p.onRampReader = onRampReader p.tokenDecimalsCache = tokenDecimalsCache - p.config.priceGetter = priceGet - p.config.sourceFeeEstimator = sourceFeeEst - p.config.sourceNative = sourceNativeTokenAddr + p.priceGetter = priceGet + p.sourceNative = sourceNativeTokenAddr + p.gasPriceEstimator = gasPriceEstimator obs, err := p.Observation(ctx, tc.epochAndRound, types.Query{}) @@ -157,62 +157,95 @@ func TestCommitReportingPlugin_Observation(t *testing.T) { } func TestCommitReportingPlugin_Report(t *testing.T) { + ctx := testutils.Context(t) + sourceChainSelector := uint64(rand.Int()) + var gasPrice prices.GasPrice = big.NewInt(1) + gasPriceHeartBeat := models.MustMakeDuration(time.Hour) + + t.Run("not enough observations", func(t *testing.T) { + tokenDecimalsCache := cache.NewMockAutoSync[map[common.Address]uint8](t) + tokenDecimalsCache.On("Get", ctx).Return(make(map[common.Address]uint8), nil) + + p := &CommitReportingPlugin{} + p.lggr = logger.TestLogger(t) + p.tokenDecimalsCache = tokenDecimalsCache + p.F = 1 + + o := CommitObservation{Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 1}, SourceGasPriceUSD: big.NewInt(0)} + obs, err := o.Marshal() + assert.NoError(t, err) + + aos := []types.AttributedObservation{{Observation: obs}} + + gotSomeReport, gotReport, err := p.Report(ctx, types.ReportTimestamp{}, types.Query{}, aos) + assert.False(t, gotSomeReport) + assert.Nil(t, gotReport) + assert.Error(t, err) + }) testCases := []struct { name string observations []CommitObservation f int - gasPriceUpdates []ccipdata.Event[price_registry.PriceRegistryUsdPerUnitGasUpdated] - tokenPriceUpdates []ccipdata.Event[price_registry.PriceRegistryUsdPerTokenUpdated] - sendRequests []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested] + gasPriceUpdates []ccipdata.Event[ccipdata.GasPriceUpdate] + tokenDecimals map[common.Address]uint8 + tokenPriceUpdates []ccipdata.Event[ccipdata.TokenPriceUpdate] + sendRequests []ccipdata.Event[internal.EVM2EVMMessage] - expCommitReport *commit_store.CommitStoreCommitReport - expSeqNumRange commit_store.CommitStoreInterval + expCommitReport *ccipdata.CommitStoreReport + expSeqNumRange ccipdata.CommitStoreInterval expErr bool }{ { name: "base", observations: []CommitObservation{ - {Interval: commit_store.CommitStoreInterval{Min: 1, Max: 1}}, - {Interval: commit_store.CommitStoreInterval{Min: 1, Max: 1}}, + {Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 1}, SourceGasPriceUSD: gasPrice}, + {Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 1}, SourceGasPriceUSD: gasPrice}, }, f: 1, - sendRequests: []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{ + sendRequests: []ccipdata.Event[internal.EVM2EVMMessage]{ { - Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - Message: evm_2_evm_onramp.InternalEVM2EVMMessage{ - SequenceNumber: 1, - }, + Data: internal.EVM2EVMMessage{ + SequenceNumber: 1, }, }, }, - expSeqNumRange: commit_store.CommitStoreInterval{Min: 1, Max: 1}, - expCommitReport: &commit_store.CommitStoreCommitReport{ - MerkleRoot: [32]byte{123}, - Interval: commit_store.CommitStoreInterval{Min: 1, Max: 1}, - PriceUpdates: commit_store.InternalPriceUpdates{ - TokenPriceUpdates: nil, - DestChainSelector: 0, - UsdPerUnitGas: big.NewInt(0), + gasPriceUpdates: []ccipdata.Event[ccipdata.GasPriceUpdate]{ + { + Data: ccipdata.GasPriceUpdate{ + GasPrice: ccipdata.GasPrice{ + DestChainSelector: sourceChainSelector, + Value: big.NewInt(1), + }, + Timestamp: big.NewInt(time.Now().Add(-2 * gasPriceHeartBeat.Duration()).Unix()), + }, }, }, - expErr: false, - }, - { - name: "not enough observations", - observations: []CommitObservation{ - {Interval: commit_store.CommitStoreInterval{Min: 1, Max: 1}}, + expSeqNumRange: ccipdata.CommitStoreInterval{Min: 1, Max: 1}, + expCommitReport: &ccipdata.CommitStoreReport{ + MerkleRoot: [32]byte{}, + Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 1}, + TokenPrices: nil, + GasPrices: []ccipdata.GasPrice{{DestChainSelector: uint64(sourceChainSelector), Value: gasPrice}}, }, - f: 1, - sendRequests: []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{{}}, - expSeqNumRange: commit_store.CommitStoreInterval{Min: 1, Max: 1}, - expErr: true, + expErr: false, }, { name: "empty", observations: []CommitObservation{ - {Interval: commit_store.CommitStoreInterval{Min: 0, Max: 0}}, - {Interval: commit_store.CommitStoreInterval{Min: 0, Max: 0}}, + {Interval: ccipdata.CommitStoreInterval{Min: 0, Max: 0}, SourceGasPriceUSD: big.NewInt(0)}, + {Interval: ccipdata.CommitStoreInterval{Min: 0, Max: 0}, SourceGasPriceUSD: big.NewInt(0)}, + }, + gasPriceUpdates: []ccipdata.Event[ccipdata.GasPriceUpdate]{ + { + Data: ccipdata.GasPriceUpdate{ + GasPrice: ccipdata.GasPrice{ + DestChainSelector: sourceChainSelector, + Value: big.NewInt(1), + }, + Timestamp: big.NewInt(time.Now().Add(-gasPriceHeartBeat.Duration() / 2).Unix()), + }, + }, }, f: 1, expErr: false, @@ -220,42 +253,52 @@ func TestCommitReportingPlugin_Report(t *testing.T) { { name: "no leaves", observations: []CommitObservation{ - {Interval: commit_store.CommitStoreInterval{Min: 2, Max: 2}}, - {Interval: commit_store.CommitStoreInterval{Min: 2, Max: 2}}, + {Interval: ccipdata.CommitStoreInterval{Min: 2, Max: 2}, SourceGasPriceUSD: big.NewInt(0)}, + {Interval: ccipdata.CommitStoreInterval{Min: 2, Max: 2}, SourceGasPriceUSD: big.NewInt(0)}, }, f: 1, - sendRequests: []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{{}}, - expSeqNumRange: commit_store.CommitStoreInterval{Min: 2, Max: 2}, + sendRequests: []ccipdata.Event[internal.EVM2EVMMessage]{{}}, + expSeqNumRange: ccipdata.CommitStoreInterval{Min: 2, Max: 2}, expErr: true, }, } - ctx := testutils.Context(t) - onRampAddress := utils.RandomAddress() - sourceChainSelector := rand.Int() - for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - destPriceRegistry, destPriceRegistryAddress := testhelpers.NewFakePriceRegistry(t) + destPriceRegistryReader := ccipdata.NewMockPriceRegistryReader(t) + destPriceRegistryReader.On("GetGasPriceUpdatesCreatedAfter", ctx, sourceChainSelector, mock.Anything, 0).Return(tc.gasPriceUpdates, nil) + destPriceRegistryReader.On("GetTokenPriceUpdatesCreatedAfter", ctx, mock.Anything, 0).Return(tc.tokenPriceUpdates, nil) - destReader := ccipdata.NewMockReader(t) - destReader.On("GetGasPriceUpdatesCreatedAfter", ctx, destPriceRegistryAddress, uint64(sourceChainSelector), mock.Anything, 0).Return(tc.gasPriceUpdates, nil) - destReader.On("GetTokenPriceUpdatesCreatedAfter", ctx, destPriceRegistryAddress, mock.Anything, 0).Return(tc.tokenPriceUpdates, nil) - - sourceReader := ccipdata.NewMockReader(t) + onRampReader := ccipdata.NewMockOnRampReader(t) if len(tc.sendRequests) > 0 { - sourceReader.On("GetSendRequestsBetweenSeqNums", ctx, onRampAddress, tc.expSeqNumRange.Min, tc.expSeqNumRange.Max, 0).Return(tc.sendRequests, nil) + onRampReader.On("GetSendRequestsBetweenSeqNums", ctx, tc.expSeqNumRange.Min, tc.expSeqNumRange.Max, 0).Return(tc.sendRequests, nil) + } + + gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) + gasPriceEstimator.On("Median", mock.Anything).Return(gasPrice, nil) + if tc.gasPriceUpdates != nil { + gasPriceEstimator.On("Deviates", mock.Anything, mock.Anything, mock.Anything).Return(false, nil) } + tokenDecimalsCache := cache.NewMockAutoSync[map[common.Address]uint8](t) + tokenDecimalsCache.On("Get", ctx).Return(tc.tokenDecimals, nil) + + lp := mocks2.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + commitStoreReader, err := ccipdata.NewCommitStoreV1_2_0(logger.TestLogger(t), utils.RandomAddress(), nil, lp, nil) + assert.NoError(t, err) + p := &CommitReportingPlugin{} p.lggr = logger.TestLogger(t) p.inflightReports = newInflightCommitReportsContainer(time.Minute) - p.destPriceRegistry = destPriceRegistry - p.config.destReader = destReader - p.config.sourceReader = sourceReader - p.config.onRampAddress = onRampAddress - p.config.sourceChainSelector = uint64(sourceChainSelector) - p.config.leafHasher = &leafHasher123{} + p.destPriceRegistryReader = destPriceRegistryReader + p.onRampReader = onRampReader + p.sourceChainSelector = sourceChainSelector + p.tokenDecimalsCache = tokenDecimalsCache + p.gasPriceEstimator = gasPriceEstimator + p.offchainConfig.GasPriceHeartBeat = gasPriceHeartBeat.Duration() + p.commitStoreReader = commitStoreReader + p.F = tc.f aos := make([]types.AttributedObservation, 0, len(tc.observations)) for _, o := range tc.observations { @@ -269,11 +312,12 @@ func TestCommitReportingPlugin_Report(t *testing.T) { assert.Error(t, err) return } + assert.NoError(t, err) if tc.expCommitReport != nil { assert.True(t, gotSomeReport) - encodedExpectedReport, err := abihelpers.EncodeCommitReport(*tc.expCommitReport) + encodedExpectedReport, err := ccipdata.EncodeCommitReport(*tc.expCommitReport) assert.NoError(t, err) assert.Equal(t, types.Report(encodedExpectedReport), gotReport) } @@ -293,18 +337,28 @@ func TestCommitReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { t.Run("report cannot be decoded leads to error", func(t *testing.T) { p := newPlugin() + encodedReport := []byte("whatever") + + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + p.commitStoreReader = commitStoreReader + commitStoreReader.On("DecodeCommitReport", encodedReport). + Return(ccipdata.CommitStoreReport{}, errors.New("unable to decode report")) + _, err := p.ShouldAcceptFinalizedReport(ctx, types.ReportTimestamp{}, encodedReport) assert.Error(t, err) }) t.Run("empty report should not be accepted", func(t *testing.T) { p := newPlugin() - report := commit_store.CommitStoreCommitReport{ - // UsdPerUnitGas is mandatory otherwise report cannot be encoded/decoded - PriceUpdates: commit_store.InternalPriceUpdates{UsdPerUnitGas: big.NewInt(int64(rand.Int()))}, - } - encodedReport, err := abihelpers.EncodeCommitReport(report) + + report := ccipdata.CommitStoreReport{} + + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + p.commitStoreReader = commitStoreReader + commitStoreReader.On("DecodeCommitReport", mock.Anything).Return(report, nil) + + encodedReport, err := ccipdata.EncodeCommitReport(report) assert.NoError(t, err) shouldAccept, err := p.ShouldAcceptFinalizedReport(ctx, types.ReportTimestamp{}, encodedReport) assert.NoError(t, err) @@ -314,19 +368,24 @@ func TestCommitReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { t.Run("stale report should not be accepted", func(t *testing.T) { onChainSeqNum := uint64(100) - commitStore, _ := testhelpers.NewFakeCommitStore(t, onChainSeqNum) + //_, _ := testhelpers.NewFakeCommitStore(t, onChainSeqNum) + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) p := newPlugin() - p.config.commitStore = commitStore - report := commit_store.CommitStoreCommitReport{ - PriceUpdates: commit_store.InternalPriceUpdates{UsdPerUnitGas: big.NewInt(int64(rand.Int()))}, - MerkleRoot: [32]byte{123}, // this report is considered non-empty since it has a merkle root + p.commitStoreReader = commitStoreReader + + report := ccipdata.CommitStoreReport{ + GasPrices: []ccipdata.GasPrice{{Value: big.NewInt(int64(rand.Int()))}}, + MerkleRoot: [32]byte{123}, // this report is considered non-empty since it has a merkle root } + commitStoreReader.On("DecodeCommitReport", mock.Anything).Return(report, nil) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(onChainSeqNum, nil) + // stale since report interval is behind on chain seq num - report.Interval = commit_store.CommitStoreInterval{Min: onChainSeqNum - 2, Max: onChainSeqNum + 10} - encodedReport, err := abihelpers.EncodeCommitReport(report) + report.Interval = ccipdata.CommitStoreInterval{Min: onChainSeqNum - 2, Max: onChainSeqNum + 10} + encodedReport, err := ccipdata.EncodeCommitReport(report) assert.NoError(t, err) shouldAccept, err := p.ShouldAcceptFinalizedReport(ctx, types.ReportTimestamp{}, encodedReport) @@ -337,28 +396,40 @@ func TestCommitReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { t.Run("non-stale report should be accepted and added inflight", func(t *testing.T) { onChainSeqNum := uint64(100) - commitStore, _ := testhelpers.NewFakeCommitStore(t, onChainSeqNum) - p := newPlugin() - p.config.commitStore = commitStore - report := commit_store.CommitStoreCommitReport{ - PriceUpdates: commit_store.InternalPriceUpdates{ - TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{ - { - SourceToken: utils.RandomAddress(), - UsdPerToken: big.NewInt(int64(rand.Int())), - }, + priceRegistryReader := ccipdata.NewMockPriceRegistryReader(t) + p.destPriceRegistryReader = priceRegistryReader + + p.lggr = logger.TestLogger(t) + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + p.commitStoreReader = commitStoreReader + + report := ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{ + Min: onChainSeqNum, + Max: onChainSeqNum + 10, + }, + TokenPrices: []ccipdata.TokenPrice{ + { + Token: utils.RandomAddress(), + Value: big.NewInt(int64(rand.Int())), + }, + }, + GasPrices: []ccipdata.GasPrice{ + { + DestChainSelector: rand.Uint64(), + Value: big.NewInt(int64(rand.Int())), }, - DestChainSelector: rand.Uint64(), - UsdPerUnitGas: big.NewInt(int64(rand.Int())), }, MerkleRoot: [32]byte{123}, } + commitStoreReader.On("DecodeCommitReport", mock.Anything).Return(report, nil) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(onChainSeqNum, nil) // non-stale since report interval is not behind on-chain seq num - report.Interval = commit_store.CommitStoreInterval{Min: onChainSeqNum, Max: onChainSeqNum + 10} - encodedReport, err := abihelpers.EncodeCommitReport(report) + report.Interval = ccipdata.CommitStoreInterval{Min: onChainSeqNum, Max: onChainSeqNum + 10} + encodedReport, err := ccipdata.EncodeCommitReport(report) assert.NoError(t, err) shouldAccept, err := p.ShouldAcceptFinalizedReport(ctx, types.ReportTimestamp{}, encodedReport) @@ -367,79 +438,243 @@ func TestCommitReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { // make sure that the report was added inflight tokenPriceUpdates := p.inflightReports.latestInflightTokenPriceUpdates() - priceUpdate := tokenPriceUpdates[report.PriceUpdates.TokenPriceUpdates[0].SourceToken] - assert.Equal(t, report.PriceUpdates.TokenPriceUpdates[0].UsdPerToken.Uint64(), priceUpdate.value.Uint64()) + priceUpdate := tokenPriceUpdates[report.TokenPrices[0].Token] + assert.Equal(t, report.TokenPrices[0].Value.Uint64(), priceUpdate.value.Uint64()) }) } func TestCommitReportingPlugin_ShouldTransmitAcceptedReport(t *testing.T) { - report := commit_store.CommitStoreCommitReport{ - PriceUpdates: commit_store.InternalPriceUpdates{ - TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{ - {SourceToken: utils.RandomAddress(), UsdPerToken: big.NewInt(9e18)}, + report := ccipdata.CommitStoreReport{ + TokenPrices: []ccipdata.TokenPrice{ + {Token: utils.RandomAddress(), Value: big.NewInt(9e18)}, + }, + GasPrices: []ccipdata.GasPrice{ + { + + DestChainSelector: rand.Uint64(), + Value: big.NewInt(2000e9), }, - DestChainSelector: rand.Uint64(), - UsdPerUnitGas: big.NewInt(2000e9), }, MerkleRoot: [32]byte{123}, } ctx := testutils.Context(t) p := &CommitReportingPlugin{} - commitStore, _ := testhelpers.NewFakeCommitStore(t, 0) - p.config.commitStore = commitStore + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + onChainSeqNum := uint64(100) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(onChainSeqNum, nil) + p.commitStoreReader = commitStoreReader p.inflightReports = newInflightCommitReportsContainer(time.Minute) p.lggr = logger.TestLogger(t) t.Run("should transmit when report is not stale", func(t *testing.T) { - onChainSeqNum := uint64(100) - commitStore.SetNextSequenceNumber(onChainSeqNum) // not-stale since report interval is not behind on chain seq num - report.Interval = commit_store.CommitStoreInterval{Min: onChainSeqNum, Max: onChainSeqNum + 10} - encodedReport, err := abihelpers.EncodeCommitReport(report) + report.Interval = ccipdata.CommitStoreInterval{Min: onChainSeqNum, Max: onChainSeqNum + 10} + encodedReport, err := ccipdata.EncodeCommitReport(report) assert.NoError(t, err) + commitStoreReader.On("DecodeCommitReport", encodedReport).Return(report, nil).Once() shouldTransmit, err := p.ShouldTransmitAcceptedReport(ctx, types.ReportTimestamp{}, encodedReport) assert.NoError(t, err) assert.True(t, shouldTransmit) }) t.Run("should not transmit when report is stale", func(t *testing.T) { - onChainSeqNum := uint64(100) - commitStore.SetNextSequenceNumber(onChainSeqNum) // stale since report interval is behind on chain seq num - report.Interval = commit_store.CommitStoreInterval{Min: onChainSeqNum - 2, Max: onChainSeqNum + 10} - encodedReport, err := abihelpers.EncodeCommitReport(report) + report.Interval = ccipdata.CommitStoreInterval{Min: onChainSeqNum - 2, Max: onChainSeqNum + 10} + encodedReport, err := ccipdata.EncodeCommitReport(report) assert.NoError(t, err) + commitStoreReader.On("DecodeCommitReport", encodedReport).Return(report, nil).Once() shouldTransmit, err := p.ShouldTransmitAcceptedReport(ctx, types.ReportTimestamp{}, encodedReport) assert.NoError(t, err) assert.False(t, shouldTransmit) }) t.Run("error when report cannot be decoded", func(t *testing.T) { - _, err := p.ShouldTransmitAcceptedReport(ctx, types.ReportTimestamp{}, []byte("whatever")) + reportBytes := []byte("whatever") + commitStoreReader.On("DecodeCommitReport", reportBytes). + Return(ccipdata.CommitStoreReport{}, errors.New("decode error")).Once() + _, err := p.ShouldTransmitAcceptedReport(ctx, types.ReportTimestamp{}, reportBytes) assert.Error(t, err) }) } +func TestCommitReportingPlugin_validateObservations(t *testing.T) { + ctx := context.Background() + + token1 := common.HexToAddress("0xa") + token2 := common.HexToAddress("0xb") + token1Price := big.NewInt(1) + token2Price := big.NewInt(2) + unsupportedToken := common.HexToAddress("0xc") + gasPrice := big.NewInt(100) + + tokenDecimals := make(map[common.Address]uint8) + tokenDecimals[token1] = 18 + tokenDecimals[token2] = 18 + + ob1 := CommitObservation{ + Interval: ccipdata.CommitStoreInterval{Min: 0, Max: 0}, + TokenPricesUSD: map[common.Address]*big.Int{ + token1: token1Price, + token2: token2Price, + }, + SourceGasPriceUSD: gasPrice, + } + ob1Bytes, err := ob1.Marshal() + assert.NoError(t, err) + var ob2, ob3 CommitObservation + _ = json.Unmarshal(ob1Bytes, &ob2) + _ = json.Unmarshal(ob1Bytes, &ob3) + + obWithNilGasPrice := CommitObservation{ + Interval: ccipdata.CommitStoreInterval{Min: 0, Max: 0}, + TokenPricesUSD: map[common.Address]*big.Int{ + token1: token1Price, + token2: token2Price, + }, + SourceGasPriceUSD: nil, + } + obWithNilTokenPrice := CommitObservation{ + Interval: ccipdata.CommitStoreInterval{Min: 0, Max: 0}, + TokenPricesUSD: map[common.Address]*big.Int{ + token1: token1Price, + token2: nil, + }, + SourceGasPriceUSD: gasPrice, + } + obMissingTokenPrices := CommitObservation{ + Interval: ccipdata.CommitStoreInterval{Min: 0, Max: 0}, + TokenPricesUSD: map[common.Address]*big.Int{}, + SourceGasPriceUSD: gasPrice, + } + obWithUnsupportedToken := CommitObservation{ + Interval: ccipdata.CommitStoreInterval{Min: 0, Max: 0}, + TokenPricesUSD: map[common.Address]*big.Int{ + token1: token1Price, + token2: token2Price, + unsupportedToken: token2Price, + }, + SourceGasPriceUSD: gasPrice, + } + obEmpty := CommitObservation{ + Interval: ccipdata.CommitStoreInterval{Min: 0, Max: 0}, + TokenPricesUSD: nil, + SourceGasPriceUSD: nil, + } + + testCases := []struct { + name string + commitObservations []CommitObservation + f int + expValidObs []CommitObservation + expError bool + }{ + { + name: "base", + commitObservations: []CommitObservation{ob1, ob2}, + f: 1, + expValidObs: []CommitObservation{ob1, ob2}, + expError: false, + }, + { + name: "pass with f=2", + commitObservations: []CommitObservation{ob1, ob2, ob3}, + f: 2, + expValidObs: []CommitObservation{ob1, ob2, ob3}, + expError: false, + }, + { + name: "tolerate 1 nil gas price with f=2", + commitObservations: []CommitObservation{ob1, ob2, ob3, obWithNilGasPrice}, + f: 2, + expValidObs: []CommitObservation{ob1, ob2, ob3}, + expError: false, + }, + { + name: "tolerate 1 nil token price with f=1", + commitObservations: []CommitObservation{ob1, ob2, obWithNilTokenPrice}, + f: 1, + expValidObs: []CommitObservation{ob1, ob2}, + expError: false, + }, + { + name: "tolerate 1 missing token prices with f=1", + commitObservations: []CommitObservation{ob1, ob2, obMissingTokenPrices}, + f: 1, + expValidObs: []CommitObservation{ob1, ob2}, + expError: false, + }, + { + name: "tolerate 1 unsupported token with f=1", + commitObservations: []CommitObservation{ob1, ob2, obWithUnsupportedToken}, + f: 1, + expValidObs: []CommitObservation{ob1, ob2}, + expError: false, + }, + { + name: "not enough valid observations", + commitObservations: []CommitObservation{ob1, ob2}, + f: 2, + expValidObs: nil, + expError: true, + }, + { + name: "too many faulty observations with f=2", + commitObservations: []CommitObservation{ob1, ob2, obMissingTokenPrices, obWithUnsupportedToken}, + f: 2, + expValidObs: nil, + expError: true, + }, + { + name: "too many faulty observations with f=1", + commitObservations: []CommitObservation{ob1, obEmpty}, + f: 1, + expValidObs: nil, + expError: true, + }, + { + name: "all faulty observations", + commitObservations: []CommitObservation{obWithNilGasPrice, obWithNilTokenPrice, obMissingTokenPrices, obWithUnsupportedToken, obEmpty}, + f: 1, + expValidObs: nil, + expError: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + obs, err := validateObservations(ctx, logger.TestLogger(t), tokenDecimals, tc.f, tc.commitObservations) + + if tc.expError { + assert.Error(t, err) + return + } + assert.Equal(t, tc.expValidObs, obs) + assert.NoError(t, err) + }) + } +} + func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { const defaultSourceChainSelector = 10 // we reuse this value across all test cases feeToken1 := common.HexToAddress("0xa") feeToken2 := common.HexToAddress("0xb") - zero := big.NewInt(0) val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } testCases := []struct { - name string - commitObservations []CommitObservation - f int - latestGasPrice update - latestTokenPrices map[common.Address]update - feeUpdateHeartBeat models.Duration - feeUpdateDeviationPPB uint32 - expGas *big.Int - expTokenUpdates []commit_store.InternalTokenPriceUpdate - expDestChainSel uint64 + name string + commitObservations []CommitObservation + f int + latestGasPrice update + latestTokenPrices map[common.Address]update + gasPriceHeartBeat models.Duration + daGasPriceDeviationPPB int64 + execGasPriceDeviationPPB int64 + tokenPriceHeartBeat models.Duration + tokenPriceDeviationPPB uint32 + expTokenUpdates []ccipdata.TokenPrice + expGasUpdates []ccipdata.GasPrice }{ { name: "median", @@ -449,30 +684,12 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { {SourceGasPriceUSD: big.NewInt(3)}, {SourceGasPriceUSD: big.NewInt(4)}, }, - f: 2, - expGas: big.NewInt(3), - expDestChainSel: defaultSourceChainSelector, - }, - { - name: "insufficient", - commitObservations: []CommitObservation{ - {SourceGasPriceUSD: nil}, - {SourceGasPriceUSD: nil}, - {SourceGasPriceUSD: big.NewInt(3)}, - }, - f: 1, - expGas: big.NewInt(0), - }, - { - name: "median including empties", - commitObservations: []CommitObservation{ - {SourceGasPriceUSD: nil}, - {SourceGasPriceUSD: big.NewInt(1)}, - {SourceGasPriceUSD: big.NewInt(2)}, + latestGasPrice: update{ + timestamp: time.Now().Add(-30 * time.Minute), // recent + value: val1e18(9), // median deviates }, - f: 1, - expGas: big.NewInt(2), - expDestChainSel: defaultSourceChainSelector, + f: 2, + expGasUpdates: []ccipdata.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: big.NewInt(3)}}, }, { name: "gas price update skipped because the latest is similar and was updated recently", @@ -480,15 +697,17 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { {SourceGasPriceUSD: val1e18(10)}, {SourceGasPriceUSD: val1e18(11)}, }, - feeUpdateHeartBeat: models.MustMakeDuration(time.Hour), - feeUpdateDeviationPPB: 20e7, + gasPriceHeartBeat: models.MustMakeDuration(time.Hour), + daGasPriceDeviationPPB: 20e7, + execGasPriceDeviationPPB: 20e7, + tokenPriceHeartBeat: models.MustMakeDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, latestGasPrice: update{ timestamp: time.Now().Add(-30 * time.Minute), // recent value: val1e18(9), // latest value close to the update }, - f: 1, - expGas: zero, - expDestChainSel: 0, + f: 1, + expGasUpdates: nil, }, { name: "gas price update included, the latest is similar but was not updated recently", @@ -496,15 +715,17 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { {SourceGasPriceUSD: val1e18(10)}, {SourceGasPriceUSD: val1e18(11)}, }, - feeUpdateHeartBeat: models.MustMakeDuration(time.Hour), - feeUpdateDeviationPPB: 20e7, + gasPriceHeartBeat: models.MustMakeDuration(time.Hour), + daGasPriceDeviationPPB: 20e7, + execGasPriceDeviationPPB: 20e7, + tokenPriceHeartBeat: models.MustMakeDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, latestGasPrice: update{ timestamp: time.Now().Add(-90 * time.Minute), // recent value: val1e18(9), // latest value close to the update }, - f: 1, - expGas: val1e18(11), - expDestChainSel: defaultSourceChainSelector, + f: 1, + expGasUpdates: []ccipdata.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: val1e18(11)}}, }, { name: "gas price update deviates from latest", @@ -513,135 +734,203 @@ func TestCommitReportingPlugin_calculatePriceUpdates(t *testing.T) { {SourceGasPriceUSD: val1e18(20)}, {SourceGasPriceUSD: val1e18(20)}, }, - feeUpdateHeartBeat: models.MustMakeDuration(time.Hour), - feeUpdateDeviationPPB: 20e7, + gasPriceHeartBeat: models.MustMakeDuration(time.Hour), + daGasPriceDeviationPPB: 20e7, + execGasPriceDeviationPPB: 20e7, + tokenPriceHeartBeat: models.MustMakeDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, latestGasPrice: update{ timestamp: time.Now().Add(-30 * time.Minute), // recent value: val1e18(11), // latest value close to the update }, - f: 2, - expGas: val1e18(20), - expDestChainSel: defaultSourceChainSelector, + f: 2, + expGasUpdates: []ccipdata.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: val1e18(20)}}, }, { name: "median one token", commitObservations: []CommitObservation{ - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(10)}}, - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(12)}}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(10)}, SourceGasPriceUSD: val1e18(0)}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(12)}, SourceGasPriceUSD: val1e18(0)}, }, f: 1, - expTokenUpdates: []commit_store.InternalTokenPriceUpdate{ - {SourceToken: feeToken1, UsdPerToken: big.NewInt(12)}, + expTokenUpdates: []ccipdata.TokenPrice{ + {Token: feeToken1, Value: big.NewInt(12)}, }, - expGas: zero, - expDestChainSel: 0, + // We expect a gas update because no latest + expGasUpdates: []ccipdata.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: big.NewInt(0)}}, }, { - name: "median two tokens, including nil", + name: "median two tokens", commitObservations: []CommitObservation{ - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: nil, feeToken2: nil}}, - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(10), feeToken2: big.NewInt(13)}}, - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(12), feeToken2: big.NewInt(7)}}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(10), feeToken2: big.NewInt(13)}, SourceGasPriceUSD: val1e18(0)}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(12), feeToken2: big.NewInt(7)}, SourceGasPriceUSD: val1e18(0)}, }, f: 1, - expTokenUpdates: []commit_store.InternalTokenPriceUpdate{ - {SourceToken: feeToken1, UsdPerToken: big.NewInt(12)}, - {SourceToken: feeToken2, UsdPerToken: big.NewInt(13)}, + expTokenUpdates: []ccipdata.TokenPrice{ + {Token: feeToken1, Value: big.NewInt(12)}, + {Token: feeToken2, Value: big.NewInt(13)}, }, - expGas: zero, - expDestChainSel: 0, + // We expect a gas update because no latest + expGasUpdates: []ccipdata.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: big.NewInt(0)}}, }, { - name: "only one token with enough votes", + name: "token price update skipped because it is close to the latest", commitObservations: []CommitObservation{ - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(10)}}, - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: big.NewInt(12), feeToken2: big.NewInt(7)}}, - }, - f: 1, - expTokenUpdates: []commit_store.InternalTokenPriceUpdate{ - {SourceToken: feeToken1, UsdPerToken: big.NewInt(12)}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(10)}, SourceGasPriceUSD: val1e18(0)}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(11)}, SourceGasPriceUSD: val1e18(0)}, + }, + f: 1, + gasPriceHeartBeat: models.MustMakeDuration(time.Hour), + daGasPriceDeviationPPB: 20e7, + execGasPriceDeviationPPB: 20e7, + tokenPriceHeartBeat: models.MustMakeDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, + latestTokenPrices: map[common.Address]update{ + feeToken1: { + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(9), + }, }, - expGas: zero, - expDestChainSel: 0, + // We expect a gas update because no latest + expGasUpdates: []ccipdata.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: big.NewInt(0)}}, }, { - name: "token price update skipped because it is close to the latest", + name: "gas price and token price both included because they are not close to the latest", commitObservations: []CommitObservation{ - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(10)}}, - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(11), feeToken2: val1e18(7)}}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(20)}, SourceGasPriceUSD: val1e18(10)}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(21)}, SourceGasPriceUSD: val1e18(11)}, + }, + f: 1, + gasPriceHeartBeat: models.MustMakeDuration(time.Hour), + daGasPriceDeviationPPB: 10e7, + execGasPriceDeviationPPB: 10e7, + tokenPriceHeartBeat: models.MustMakeDuration(time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: update{ + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(9), }, - f: 1, - feeUpdateHeartBeat: models.MustMakeDuration(time.Hour), - feeUpdateDeviationPPB: 20e7, latestTokenPrices: map[common.Address]update{ feeToken1: { timestamp: time.Now().Add(-30 * time.Minute), value: val1e18(9), }, }, - expGas: zero, - expDestChainSel: 0, + expTokenUpdates: []ccipdata.TokenPrice{ + {Token: feeToken1, Value: val1e18(21)}, + }, + expGasUpdates: []ccipdata.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: val1e18(11)}}, }, { - name: "token price update is close to the latest but included because it has not been updated recently", + name: "gas price and token price both included because they not been updated recently", commitObservations: []CommitObservation{ - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(10)}}, - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(11), feeToken2: val1e18(7)}}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(20)}, SourceGasPriceUSD: val1e18(10)}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(21)}, SourceGasPriceUSD: val1e18(11)}, + }, + f: 1, + gasPriceHeartBeat: models.MustMakeDuration(time.Hour), + daGasPriceDeviationPPB: 10e7, + execGasPriceDeviationPPB: 10e7, + tokenPriceHeartBeat: models.MustMakeDuration(2 * time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: update{ + timestamp: time.Now().Add(-90 * time.Minute), + value: val1e18(11), }, - f: 1, - feeUpdateHeartBeat: models.MustMakeDuration(50 * time.Minute), - feeUpdateDeviationPPB: 20e7, latestTokenPrices: map[common.Address]update{ feeToken1: { - timestamp: time.Now().Add(-1 * time.Hour), - value: val1e18(9), + timestamp: time.Now().Add(-4 * time.Hour), + value: val1e18(21), }, }, - expTokenUpdates: []commit_store.InternalTokenPriceUpdate{ - {SourceToken: feeToken1, UsdPerToken: val1e18(11)}, + expTokenUpdates: []ccipdata.TokenPrice{ + {Token: feeToken1, Value: val1e18(21)}, }, - expGas: zero, - expDestChainSel: 0, + expGasUpdates: []ccipdata.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: val1e18(11)}}, }, { - name: "token price update included because it is not close to the latest", + name: "gas price included because it deviates from latest and token price skipped because it does not deviate", commitObservations: []CommitObservation{ - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(20)}}, - {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(21), feeToken2: val1e18(7)}}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(20)}, SourceGasPriceUSD: val1e18(10)}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(21)}, SourceGasPriceUSD: val1e18(11)}, + }, + f: 1, + gasPriceHeartBeat: models.MustMakeDuration(time.Hour), + daGasPriceDeviationPPB: 10e7, + execGasPriceDeviationPPB: 10e7, + tokenPriceHeartBeat: models.MustMakeDuration(2 * time.Hour), + tokenPriceDeviationPPB: 200e7, + latestGasPrice: update{ + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(9), }, - f: 1, - feeUpdateHeartBeat: models.MustMakeDuration(time.Hour), - feeUpdateDeviationPPB: 20e7, latestTokenPrices: map[common.Address]update{ feeToken1: { timestamp: time.Now().Add(-30 * time.Minute), value: val1e18(9), }, }, - expTokenUpdates: []commit_store.InternalTokenPriceUpdate{ - {SourceToken: feeToken1, UsdPerToken: val1e18(21)}, + expGasUpdates: []ccipdata.GasPrice{{DestChainSelector: defaultSourceChainSelector, Value: val1e18(11)}}, + }, + { + name: "gas price skipped because it does not deviate and token price included because it has not been updated recently", + commitObservations: []CommitObservation{ + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(20)}, SourceGasPriceUSD: val1e18(10)}, + {TokenPricesUSD: map[common.Address]*big.Int{feeToken1: val1e18(21)}, SourceGasPriceUSD: val1e18(11)}, + }, + f: 1, + gasPriceHeartBeat: models.MustMakeDuration(time.Hour), + daGasPriceDeviationPPB: 10e7, + execGasPriceDeviationPPB: 10e7, + tokenPriceHeartBeat: models.MustMakeDuration(2 * time.Hour), + tokenPriceDeviationPPB: 20e7, + latestGasPrice: update{ + timestamp: time.Now().Add(-30 * time.Minute), + value: val1e18(11), + }, + latestTokenPrices: map[common.Address]update{ + feeToken1: { + timestamp: time.Now().Add(-4 * time.Hour), + value: val1e18(21), + }, + }, + expTokenUpdates: []ccipdata.TokenPrice{ + {Token: feeToken1, Value: val1e18(21)}, }, - expGas: zero, - expDestChainSel: 0, + expGasUpdates: nil, }, } + evmEstimator := mocks.NewEvmFeeEstimator(t) + evmEstimator.On("L1Oracle").Return(nil) + estimatorCSVer, _ := semver.NewVersion("1.2.0") + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + estimator, _ := prices.NewGasPriceEstimatorForCommitPlugin( + *estimatorCSVer, + evmEstimator, + nil, + tc.daGasPriceDeviationPPB, + tc.execGasPriceDeviationPPB, + ) + r := &CommitReportingPlugin{ - lggr: logger.TestLogger(t), - config: CommitPluginConfig{sourceChainSelector: defaultSourceChainSelector}, - offchainConfig: ccipconfig.CommitOffchainConfig{ - FeeUpdateHeartBeat: tc.feeUpdateHeartBeat, - FeeUpdateDeviationPPB: tc.feeUpdateDeviationPPB, + lggr: logger.TestLogger(t), + sourceChainSelector: defaultSourceChainSelector, + offchainConfig: ccipdata.CommitOffchainConfig{ + GasPriceHeartBeat: tc.gasPriceHeartBeat.Duration(), + TokenPriceHeartBeat: tc.tokenPriceHeartBeat.Duration(), + TokenPriceDeviationPPB: tc.tokenPriceDeviationPPB, }, - F: tc.f, + gasPriceEstimator: estimator, + F: tc.f, } - got := r.calculatePriceUpdates(tc.commitObservations, tc.latestGasPrice, tc.latestTokenPrices) + gotTokens, gotGas, err := r.calculatePriceUpdates(tc.commitObservations, tc.latestGasPrice, tc.latestTokenPrices) - assert.Equal(t, tc.expGas, got.UsdPerUnitGas) - assert.Equal(t, tc.expTokenUpdates, got.TokenPriceUpdates) - assert.Equal(t, tc.expDestChainSel, got.DestChainSelector) + assert.Equal(t, tc.expGasUpdates, gotGas) + assert.Equal(t, tc.expTokenUpdates, gotTokens) + assert.NoError(t, err) }) } } @@ -657,17 +946,17 @@ func TestCommitReportingPlugin_generatePriceUpdates(t *testing.T) { sort.Slice(tokens, func(i, j int) bool { return tokens[i].String() < tokens[j].String() }) testCases := []struct { - name string - tokenDecimals map[common.Address]uint8 - sourceNativeToken common.Address - priceGetterRespData map[common.Address]*big.Int - priceGetterRespErr error - sourceFeeEstimatorRespFee gas.EvmFee - sourceFeeEstimatorRespErr error - maxGasPrice uint64 - expSourceGasPriceUSD *big.Int - expTokenPricesUSD map[common.Address]*big.Int - expErr bool + name string + tokenDecimals map[common.Address]uint8 + sourceNativeToken common.Address + priceGetterRespData map[common.Address]*big.Int + priceGetterRespErr error + feeEstimatorRespFee prices.GasPrice + feeEstimatorRespErr error + maxGasPrice uint64 + expSourceGasPriceUSD *big.Int + expTokenPricesUSD map[common.Address]*big.Int + expErr bool }{ { name: "base", @@ -681,15 +970,11 @@ func TestCommitReportingPlugin_generatePriceUpdates(t *testing.T) { tokens[1]: val1e18(200), tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) }, - priceGetterRespErr: nil, - sourceFeeEstimatorRespFee: gas.EvmFee{ - Legacy: assets.NewWei(big.NewInt(10)), - DynamicFeeCap: nil, - DynamicTipCap: nil, - }, - sourceFeeEstimatorRespErr: nil, - maxGasPrice: 1e18, - expSourceGasPriceUSD: big.NewInt(1000), + priceGetterRespErr: nil, + feeEstimatorRespFee: big.NewInt(10), + feeEstimatorRespErr: nil, + maxGasPrice: 1e18, + expSourceGasPriceUSD: big.NewInt(1000), expTokenPricesUSD: map[common.Address]*big.Int{ tokens[0]: val1e18(100), tokens[1]: val1e18(200), @@ -746,15 +1031,11 @@ func TestCommitReportingPlugin_generatePriceUpdates(t *testing.T) { tokens[1]: val1e18(200), tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it }, - priceGetterRespErr: nil, - sourceFeeEstimatorRespFee: gas.EvmFee{ - Legacy: assets.NewWei(big.NewInt(10)), - DynamicFeeCap: nil, - DynamicTipCap: nil, - }, - sourceFeeEstimatorRespErr: nil, - maxGasPrice: 1e18, - expSourceGasPriceUSD: big.NewInt(1000), + priceGetterRespErr: nil, + feeEstimatorRespFee: big.NewInt(10), + feeEstimatorRespErr: nil, + maxGasPrice: 1e18, + expSourceGasPriceUSD: big.NewInt(1000), expTokenPricesUSD: map[common.Address]*big.Int{ tokens[0]: val1e18(100), tokens[1]: val1e18(200), @@ -773,15 +1054,11 @@ func TestCommitReportingPlugin_generatePriceUpdates(t *testing.T) { tokens[1]: val1e18(200), tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) }, - priceGetterRespErr: nil, - sourceFeeEstimatorRespFee: gas.EvmFee{ - Legacy: assets.NewWei(big.NewInt(10)), - DynamicFeeCap: assets.NewWei(big.NewInt(20)), - DynamicTipCap: nil, - }, - sourceFeeEstimatorRespErr: nil, - maxGasPrice: 1e18, - expSourceGasPriceUSD: big.NewInt(2000), + priceGetterRespErr: nil, + feeEstimatorRespFee: big.NewInt(20), + feeEstimatorRespErr: nil, + maxGasPrice: 1e18, + expSourceGasPriceUSD: big.NewInt(2000), expTokenPricesUSD: map[common.Address]*big.Int{ tokens[0]: val1e18(100), tokens[1]: val1e18(200), @@ -800,13 +1077,9 @@ func TestCommitReportingPlugin_generatePriceUpdates(t *testing.T) { tokens[1]: val1e18(200), tokens[2]: val1e18(300), // price getter returned a price for this token even though we didn't request it (should be skipped) }, - sourceFeeEstimatorRespFee: gas.EvmFee{ - Legacy: nil, - DynamicFeeCap: nil, - DynamicTipCap: nil, - }, - maxGasPrice: 1e18, - expErr: true, + feeEstimatorRespFee: nil, + maxGasPrice: 1e18, + expErr: true, }, } @@ -815,8 +1088,8 @@ func TestCommitReportingPlugin_generatePriceUpdates(t *testing.T) { priceGetter := pricegetter.NewMockPriceGetter(t) defer priceGetter.AssertExpectations(t) - sourceFeeEstimator := mocks.NewEvmFeeEstimator(t) - defer sourceFeeEstimator.AssertExpectations(t) + gasPriceEstimator := prices.NewMockGasPriceEstimatorCommit(t) + defer gasPriceEstimator.AssertExpectations(t) tokens := make([]common.Address, 0, len(tc.tokenDecimals)) for tk := range tc.tokenDecimals { @@ -830,17 +1103,18 @@ func TestCommitReportingPlugin_generatePriceUpdates(t *testing.T) { } if tc.maxGasPrice > 0 { - sourceFeeEstimator.On("GetFee", mock.Anything, []byte(nil), uint32(0), assets.NewWei(big.NewInt(int64(tc.maxGasPrice)))).Return( - tc.sourceFeeEstimatorRespFee, uint32(0), tc.sourceFeeEstimatorRespErr) + gasPriceEstimator.On("GetGasPrice", mock.Anything).Return(tc.feeEstimatorRespFee, tc.feeEstimatorRespErr) + if tc.feeEstimatorRespFee != nil { + var pUSD prices.GasPrice = ccipcalc.CalculateUsdPerUnitGas(tc.feeEstimatorRespFee, tc.expTokenPricesUSD[tc.sourceNativeToken]) + gasPriceEstimator.On("DenoteInUSD", mock.Anything, mock.Anything).Return(pUSD, nil) + } } p := &CommitReportingPlugin{ - config: CommitPluginConfig{ - sourceNative: tc.sourceNativeToken, - priceGetter: priceGetter, - sourceFeeEstimator: sourceFeeEstimator, - }, - offchainConfig: ccipconfig.CommitOffchainConfig{MaxGasPrice: tc.maxGasPrice}, + sourceNative: tc.sourceNativeToken, + priceGetter: priceGetter, + //offchainConfig: ccipdata.CommitOffchainConfig{MaxGasPrice: tc.maxGasPrice}, + gasPriceEstimator: gasPriceEstimator, } sourceGasPriceUSD, tokenPricesUSD, err := p.generatePriceUpdates(context.Background(), logger.TestLogger(t), tc.tokenDecimals) @@ -861,7 +1135,7 @@ func TestCommitReportingPlugin_nextMinSeqNum(t *testing.T) { var tt = []struct { onChainMin uint64 - inflight []commit_store.CommitStoreCommitReport + inflight []ccipdata.CommitStoreReport expectedOnChainMin uint64 expectedInflightMin uint64 }{ @@ -873,32 +1147,34 @@ func TestCommitReportingPlugin_nextMinSeqNum(t *testing.T) { }, { onChainMin: uint64(1), - inflight: []commit_store.CommitStoreCommitReport{ - {Interval: commit_store.CommitStoreInterval{Min: uint64(1), Max: uint64(2)}, MerkleRoot: root1}}, + inflight: []ccipdata.CommitStoreReport{ + {Interval: ccipdata.CommitStoreInterval{Min: uint64(1), Max: uint64(2)}, MerkleRoot: root1}}, expectedInflightMin: uint64(3), expectedOnChainMin: uint64(1), }, { onChainMin: uint64(1), - inflight: []commit_store.CommitStoreCommitReport{ - {Interval: commit_store.CommitStoreInterval{Min: uint64(3), Max: uint64(4)}, MerkleRoot: root1}}, + inflight: []ccipdata.CommitStoreReport{ + {Interval: ccipdata.CommitStoreInterval{Min: uint64(3), Max: uint64(4)}, MerkleRoot: root1}}, expectedInflightMin: uint64(5), expectedOnChainMin: uint64(1), }, { onChainMin: uint64(1), - inflight: []commit_store.CommitStoreCommitReport{ - {Interval: commit_store.CommitStoreInterval{Min: uint64(1), Max: uint64(MaxInflightSeqNumGap + 2)}, MerkleRoot: root1}}, + inflight: []ccipdata.CommitStoreReport{ + {Interval: ccipdata.CommitStoreInterval{Min: uint64(1), Max: uint64(MaxInflightSeqNumGap + 2)}, MerkleRoot: root1}}, expectedInflightMin: uint64(1), expectedOnChainMin: uint64(1), }, } for _, tc := range tt { - commitStore, _ := testhelpers.NewFakeCommitStore(t, tc.onChainMin) - cp := CommitReportingPlugin{config: CommitPluginConfig{commitStore: commitStore}, inflightReports: newInflightCommitReportsContainer(time.Hour)} + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(tc.onChainMin, nil).Maybe() + cp := CommitReportingPlugin{commitStoreReader: commitStoreReader, inflightReports: newInflightCommitReportsContainer(time.Hour)} epochAndRound := uint64(1) for _, rep := range tc.inflight { rc := rep + rc.GasPrices = []ccipdata.GasPrice{{}} require.NoError(t, cp.inflightReports.add(lggr, rc, epochAndRound)) epochAndRound++ } @@ -918,40 +1194,41 @@ func TestCommitReportingPlugin_isStaleReport(t *testing.T) { merkleRoot2 := utils.Keccak256Fixed([]byte("some merkle root 2")) t.Run("empty report", func(t *testing.T) { - commitStore, _ := testhelpers.NewFakeCommitStore(t, 1) - r := &CommitReportingPlugin{config: CommitPluginConfig{commitStore: commitStore}} - isStale := r.isStaleReport(ctx, lggr, commit_store.CommitStoreCommitReport{}, false, types.ReportTimestamp{}) + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + r := &CommitReportingPlugin{commitStoreReader: commitStoreReader} + isStale := r.isStaleReport(ctx, lggr, ccipdata.CommitStoreReport{}, false, types.ReportTimestamp{}) assert.True(t, isStale) }) t.Run("merkle root", func(t *testing.T) { const expNextSeqNum = uint64(9) - commitStore, _ := testhelpers.NewFakeCommitStore(t, expNextSeqNum) + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(expNextSeqNum, nil) r := &CommitReportingPlugin{ - config: CommitPluginConfig{commitStore: commitStore}, + commitStoreReader: commitStoreReader, inflightReports: &inflightCommitReportsContainer{ inFlight: map[[32]byte]InflightCommitReport{ merkleRoot2: { - report: commit_store.CommitStoreCommitReport{ - Interval: commit_store.CommitStoreInterval{Min: expNextSeqNum + 1, Max: expNextSeqNum + 10}, + report: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: expNextSeqNum + 1, Max: expNextSeqNum + 10}, }, }, }, }, } - assert.False(t, r.isStaleReport(ctx, lggr, commit_store.CommitStoreCommitReport{ + assert.False(t, r.isStaleReport(ctx, lggr, ccipdata.CommitStoreReport{ MerkleRoot: merkleRoot1, - Interval: commit_store.CommitStoreInterval{Min: expNextSeqNum + 1, Max: expNextSeqNum + 10}, + Interval: ccipdata.CommitStoreInterval{Min: expNextSeqNum + 1, Max: expNextSeqNum + 10}, }, false, types.ReportTimestamp{})) - assert.True(t, r.isStaleReport(ctx, lggr, commit_store.CommitStoreCommitReport{ + assert.True(t, r.isStaleReport(ctx, lggr, ccipdata.CommitStoreReport{ MerkleRoot: merkleRoot1, - Interval: commit_store.CommitStoreInterval{Min: expNextSeqNum + 1, Max: expNextSeqNum + 10}, + Interval: ccipdata.CommitStoreInterval{Min: expNextSeqNum + 1, Max: expNextSeqNum + 10}, }, true, types.ReportTimestamp{})) - assert.True(t, r.isStaleReport(ctx, lggr, commit_store.CommitStoreCommitReport{ + assert.True(t, r.isStaleReport(ctx, lggr, ccipdata.CommitStoreReport{ MerkleRoot: merkleRoot1}, false, types.ReportTimestamp{})) }) } @@ -1019,14 +1296,15 @@ func TestCommitReportingPlugin_calculateMinMaxSequenceNumbers(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { p := &CommitReportingPlugin{} - commitStore, _ := testhelpers.NewFakeCommitStore(t, tc.commitStoreSeqNum) - p.config.commitStore = commitStore + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + commitStoreReader.On("GetExpectedNextSequenceNumber", mock.Anything).Return(tc.commitStoreSeqNum, nil) + p.commitStoreReader = commitStoreReader p.inflightReports = newInflightCommitReportsContainer(time.Minute) if tc.inflightSeqNum > 0 { p.inflightReports.inFlight[[32]byte{}] = InflightCommitReport{ - report: commit_store.CommitStoreCommitReport{ - Interval: commit_store.CommitStoreInterval{ + report: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{ Min: tc.inflightSeqNum, Max: tc.inflightSeqNum, }, @@ -1034,17 +1312,17 @@ func TestCommitReportingPlugin_calculateMinMaxSequenceNumbers(t *testing.T) { } } - sourceReader := ccipdata.NewMockReader(t) - var sendReqs []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested] + onRampReader := ccipdata.NewMockOnRampReader(t) + var sendReqs []ccipdata.Event[internal.EVM2EVMMessage] for _, seqNum := range tc.msgSeqNums { - sendReqs = append(sendReqs, ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{ - Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - Message: evm_2_evm_onramp.InternalEVM2EVMMessage{SequenceNumber: seqNum}, + sendReqs = append(sendReqs, ccipdata.Event[internal.EVM2EVMMessage]{ + Data: internal.EVM2EVMMessage{ + SequenceNumber: seqNum, }, }) } - sourceReader.On("GetSendRequestsGteSeqNum", ctx, mock.Anything, tc.expQueryMin, false, 0).Return(sendReqs, nil) - p.config.sourceReader = sourceReader + onRampReader.On("GetSendRequestsGteSeqNum", ctx, tc.expQueryMin, 0).Return(sendReqs, nil) + p.onRampReader = onRampReader minSeqNum, maxSeqNum, err := p.calculateMinMaxSequenceNumbers(ctx, lggr) if tc.expErr { @@ -1060,6 +1338,7 @@ func TestCommitReportingPlugin_calculateMinMaxSequenceNumbers(t *testing.T) { func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { now := time.Now() + chainSelector := uint64(1234) testCases := []struct { name string @@ -1079,7 +1358,7 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { { name: "inflight price is nil", checkInflight: true, - inflightGasPriceUpdate: &update{timestamp: now, value: nil}, + inflightGasPriceUpdate: nil, destGasPriceUpdates: []update{ {timestamp: now.Add(time.Minute), value: big.NewInt(2000)}, {timestamp: now.Add(2 * time.Minute), value: big.NewInt(3000)}, @@ -1105,37 +1384,38 @@ func TestCommitReportingPlugin_getLatestGasPriceUpdate(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { p := &CommitReportingPlugin{} + p.sourceChainSelector = chainSelector p.inflightReports = newInflightCommitReportsContainer(time.Minute) p.lggr = lggr - destPriceRegistry, _ := testhelpers.NewFakePriceRegistry(t) - p.destPriceRegistry = destPriceRegistry + destPriceRegistry := ccipdata.NewMockPriceRegistryReader(t) + p.destPriceRegistryReader = destPriceRegistry if tc.inflightGasPriceUpdate != nil { p.inflightReports.inFlightPriceUpdates = append( p.inflightReports.inFlightPriceUpdates, InflightPriceUpdate{ createdAt: tc.inflightGasPriceUpdate.timestamp, - priceUpdates: commit_store.InternalPriceUpdates{ - DestChainSelector: 1234, - UsdPerUnitGas: tc.inflightGasPriceUpdate.value, - }, + gasPrices: []ccipdata.GasPrice{{ + DestChainSelector: chainSelector, + Value: tc.inflightGasPriceUpdate.value, + }}, }, ) } if len(tc.destGasPriceUpdates) > 0 { - var events []ccipdata.Event[price_registry.PriceRegistryUsdPerUnitGasUpdated] + var events []ccipdata.Event[ccipdata.GasPriceUpdate] for _, u := range tc.destGasPriceUpdates { - events = append(events, ccipdata.Event[price_registry.PriceRegistryUsdPerUnitGasUpdated]{ - Data: price_registry.PriceRegistryUsdPerUnitGasUpdated{ - Value: u.value, + events = append(events, ccipdata.Event[ccipdata.GasPriceUpdate]{ + Data: ccipdata.GasPriceUpdate{ + GasPrice: ccipdata.GasPrice{Value: u.value}, Timestamp: big.NewInt(u.timestamp.Unix()), }, }) } - destReader := ccipdata.NewMockReader(t) - destReader.On("GetGasPriceUpdatesCreatedAfter", ctx, mock.Anything, uint64(0), mock.Anything, 0).Return(events, nil) - p.config.destReader = destReader + destReader := ccipdata.NewMockPriceRegistryReader(t) + destReader.On("GetGasPriceUpdatesCreatedAfter", ctx, chainSelector, mock.Anything, 0).Return(events, nil) + p.destPriceRegistryReader = destReader } priceUpdate, err := p.getLatestGasPriceUpdate(ctx, time.Now(), tc.checkInflight) @@ -1158,7 +1438,7 @@ func TestCommitReportingPlugin_getLatestTokenPriceUpdates(t *testing.T) { testCases := []struct { name string - priceRegistryUpdates []price_registry.PriceRegistryUsdPerTokenUpdated + priceRegistryUpdates []ccipdata.TokenPriceUpdate checkInflight bool inflightUpdates map[common.Address]update expUpdates map[common.Address]update @@ -1166,15 +1446,19 @@ func TestCommitReportingPlugin_getLatestTokenPriceUpdates(t *testing.T) { }{ { name: "ignore inflight updates", - priceRegistryUpdates: []price_registry.PriceRegistryUsdPerTokenUpdated{ + priceRegistryUpdates: []ccipdata.TokenPriceUpdate{ { - Token: tk1, - Value: big.NewInt(1000), + TokenPrice: ccipdata.TokenPrice{ + Token: tk1, + Value: big.NewInt(1000), + }, Timestamp: big.NewInt(now.Add(1 * time.Minute).Unix()), }, { - Token: tk2, - Value: big.NewInt(2000), + TokenPrice: ccipdata.TokenPrice{ + Token: tk2, + Value: big.NewInt(2000), + }, Timestamp: big.NewInt(now.Add(2 * time.Minute).Unix()), }, }, @@ -1187,15 +1471,19 @@ func TestCommitReportingPlugin_getLatestTokenPriceUpdates(t *testing.T) { }, { name: "consider inflight updates", - priceRegistryUpdates: []price_registry.PriceRegistryUsdPerTokenUpdated{ + priceRegistryUpdates: []ccipdata.TokenPriceUpdate{ { - Token: tk1, - Value: big.NewInt(1000), + TokenPrice: ccipdata.TokenPrice{ + Token: tk1, + Value: big.NewInt(1000), + }, Timestamp: big.NewInt(now.Add(1 * time.Minute).Unix()), }, { - Token: tk2, - Value: big.NewInt(2000), + TokenPrice: ccipdata.TokenPrice{ + Token: tk2, + Value: big.NewInt(2000), + }, Timestamp: big.NewInt(now.Add(2 * time.Minute).Unix()), }, }, @@ -1217,32 +1505,27 @@ func TestCommitReportingPlugin_getLatestTokenPriceUpdates(t *testing.T) { t.Run(tc.name, func(t *testing.T) { p := &CommitReportingPlugin{} - priceReg, priceRegAddr := testhelpers.NewFakePriceRegistry(t) - p.destPriceRegistry = priceReg + //_, priceRegAddr := testhelpers.NewFakePriceRegistry(t) + priceReg := ccipdata.NewMockPriceRegistryReader(t) + p.destPriceRegistryReader = priceReg - destReader := ccipdata.NewMockReader(t) - var events []ccipdata.Event[price_registry.PriceRegistryUsdPerTokenUpdated] + //destReader := ccipdata.NewMockReader(t) + var events []ccipdata.Event[ccipdata.TokenPriceUpdate] for _, up := range tc.priceRegistryUpdates { - events = append(events, ccipdata.Event[price_registry.PriceRegistryUsdPerTokenUpdated]{ - Data: price_registry.PriceRegistryUsdPerTokenUpdated{ - Token: up.Token, - Value: up.Value, - Timestamp: up.Timestamp, - }, + events = append(events, ccipdata.Event[ccipdata.TokenPriceUpdate]{ + Data: up, }) } - destReader.On("GetTokenPriceUpdatesCreatedAfter", ctx, priceRegAddr, mock.Anything, 0).Return(events, nil) - p.config.destReader = destReader + //destReader.On("GetTokenPriceUpdatesCreatedAfter", ctx, priceRegAddr, mock.Anything, 0).Return(events, nil) + priceReg.On("GetTokenPriceUpdatesCreatedAfter", ctx, mock.Anything, 0).Return(events, nil) p.inflightReports = newInflightCommitReportsContainer(time.Minute) if len(tc.inflightUpdates) > 0 { for tk, upd := range tc.inflightUpdates { p.inflightReports.inFlightPriceUpdates = append(p.inflightReports.inFlightPriceUpdates, InflightPriceUpdate{ createdAt: upd.timestamp, - priceUpdates: commit_store.InternalPriceUpdates{ - TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{ - {SourceToken: tk, UsdPerToken: upd.value}, - }, + tokenPrices: []ccipdata.TokenPrice{ + {Token: tk, Value: upd.value}, }, }) } @@ -1271,13 +1554,15 @@ func Test_commitReportSize(t *testing.T) { p.Property("bounded commit report size", prop.ForAll(func(root []byte, min, max uint64) bool { var root32 [32]byte copy(root32[:], root) - rep, err := abihelpers.EncodeCommitReport(commit_store.CommitStoreCommitReport{ - MerkleRoot: root32, - Interval: commit_store.CommitStoreInterval{Min: min, Max: max}, - PriceUpdates: commit_store.InternalPriceUpdates{ - TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{}, - DestChainSelector: 1337, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + rep, err := ccipdata.EncodeCommitReport(ccipdata.CommitStoreReport{ + MerkleRoot: root32, + Interval: ccipdata.CommitStoreInterval{Min: min, Max: max}, + TokenPrices: []ccipdata.TokenPrice{}, + GasPrices: []ccipdata.GasPrice{ + { + DestChainSelector: 1337, + Value: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, }, }) require.NoError(t, err) @@ -1289,27 +1574,26 @@ func Test_commitReportSize(t *testing.T) { func Test_calculateIntervalConsensus(t *testing.T) { tests := []struct { name string - intervals []commit_store.CommitStoreInterval + intervals []ccipdata.CommitStoreInterval rangeLimit uint64 f int wantMin uint64 wantMax uint64 wantErr bool }{ - {"no obs", []commit_store.CommitStoreInterval{{Min: 0, Max: 0}}, 0, 0, 0, 0, false}, - {"basic", []commit_store.CommitStoreInterval{ + {"no obs", []ccipdata.CommitStoreInterval{{Min: 0, Max: 0}}, 0, 0, 0, 0, false}, + {"basic", []ccipdata.CommitStoreInterval{ {Min: 9, Max: 14}, {Min: 10, Max: 12}, {Min: 10, Max: 14}, }, 0, 1, 10, 14, false}, - {"not enough intervals", []commit_store.CommitStoreInterval{}, 0, 1, 0, 0, true}, - {"min > max", []commit_store.CommitStoreInterval{ + {"min > max", []ccipdata.CommitStoreInterval{ {Min: 9, Max: 4}, {Min: 10, Max: 4}, {Min: 10, Max: 6}, }, 0, 1, 0, 0, true}, { - "range limit", []commit_store.CommitStoreInterval{ + "range limit", []ccipdata.CommitStoreInterval{ {Min: 10, Max: 100}, {Min: 1, Max: 1000}, }, 256, 1, 10, 265, false, @@ -1393,29 +1677,26 @@ func TestCommitReportToEthTxMeta(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - report := commit_store.CommitStoreCommitReport{ - PriceUpdates: commit_store.InternalPriceUpdates{ - TokenPriceUpdates: []commit_store.InternalTokenPriceUpdate{}, - DestChainSelector: uint64(1337), - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + report := ccipdata.CommitStoreReport{ + TokenPrices: []ccipdata.TokenPrice{}, + GasPrices: []ccipdata.GasPrice{ + { + DestChainSelector: uint64(1337), + Value: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, }, MerkleRoot: tree.Root(), - Interval: commit_store.CommitStoreInterval{Min: tc.min, Max: tc.max}, + Interval: ccipdata.CommitStoreInterval{Min: tc.min, Max: tc.max}, } - out, err := abihelpers.EncodeCommitReport(report) + out, err := ccipdata.EncodeCommitReport(report) require.NoError(t, err) - txMeta, err := CommitReportToEthTxMeta(out) + fn, err := ccipdata.CommitReportToEthTxMeta(ccipconfig.CommitStore, *semver.MustParse("1.0.0")) + require.NoError(t, err) + txMeta, err := fn(out) require.NoError(t, err) require.NotNil(t, txMeta) - require.EqualValues(t, tc.expectedRange, txMeta.SeqNumbers) + //require.EqualValues(t, tc.expectedRange, txMeta.SeqNumbers) // TODO: the commit store intervals are not decoded }) } } - -// leafHasher123 always returns '123' followed by zeroes in HashLeaf method. -type leafHasher123 struct{} - -func (h leafHasher123) HashLeaf(_ gethtypes.Log) ([32]byte, error) { - return [32]byte{123}, nil -} diff --git a/core/services/ocr2/plugins/ccip/config/offchain_config.go b/core/services/ocr2/plugins/ccip/config/offchain_config.go index bdcb0e77cd..f8fba3f1bc 100644 --- a/core/services/ocr2/plugins/ccip/config/offchain_config.go +++ b/core/services/ocr2/plugins/ccip/config/offchain_config.go @@ -2,92 +2,12 @@ package config import ( "encoding/json" - - "github.com/pkg/errors" - - "github.com/smartcontractkit/chainlink/v2/core/store/models" ) type OffchainConfig interface { Validate() error } -// Do not change the JSON format of this struct without consulting with -// the RDD people first. -type CommitOffchainConfig struct { - SourceFinalityDepth uint32 - DestFinalityDepth uint32 - FeeUpdateHeartBeat models.Duration - FeeUpdateDeviationPPB uint32 - MaxGasPrice uint64 - InflightCacheExpiry models.Duration -} - -func (c CommitOffchainConfig) Validate() error { - if c.SourceFinalityDepth == 0 { - return errors.New("must set SourceFinalityDepth") - } - if c.DestFinalityDepth == 0 { - return errors.New("must set DestFinalityDepth") - } - if c.FeeUpdateHeartBeat.Duration() == 0 { - return errors.New("must set FeeUpdateHeartBeat") - } - if c.FeeUpdateDeviationPPB == 0 { - return errors.New("must set FeeUpdateDeviationPPB") - } - if c.MaxGasPrice == 0 { - return errors.New("must set MaxGasPrice") - } - if c.InflightCacheExpiry.Duration() == 0 { - return errors.New("must set InflightCacheExpiry") - } - - return nil -} - -// Do not change the JSON format of this struct without consulting with -// the RDD people first. -type ExecOffchainConfig struct { - SourceFinalityDepth uint32 - DestOptimisticConfirmations uint32 - DestFinalityDepth uint32 - BatchGasLimit uint32 - RelativeBoostPerWaitHour float64 - MaxGasPrice uint64 - InflightCacheExpiry models.Duration - RootSnoozeTime models.Duration -} - -func (c ExecOffchainConfig) Validate() error { - if c.SourceFinalityDepth == 0 { - return errors.New("must set SourceFinalityDepth") - } - if c.DestFinalityDepth == 0 { - return errors.New("must set DestFinalityDepth") - } - if c.DestOptimisticConfirmations == 0 { - return errors.New("must set DestOptimisticConfirmations") - } - if c.BatchGasLimit == 0 { - return errors.New("must set BatchGasLimit") - } - if c.RelativeBoostPerWaitHour == 0 { - return errors.New("must set RelativeBoostPerWaitHour") - } - if c.MaxGasPrice == 0 { - return errors.New("must set MaxGasPrice") - } - if c.InflightCacheExpiry.Duration() == 0 { - return errors.New("must set InflightCacheExpiry") - } - if c.RootSnoozeTime.Duration() == 0 { - return errors.New("must set RootSnoozeTime") - } - - return nil -} - func DecodeOffchainConfig[T OffchainConfig](encodedConfig []byte) (T, error) { var result T err := json.Unmarshal(encodedConfig, &result) diff --git a/core/services/ocr2/plugins/ccip/config/onchain_config.go b/core/services/ocr2/plugins/ccip/config/onchain_config.go index fcd8b3715c..d912156bec 100644 --- a/core/services/ocr2/plugins/ccip/config/onchain_config.go +++ b/core/services/ocr2/plugins/ccip/config/onchain_config.go @@ -1,73 +1 @@ package config - -import ( - "errors" - "time" - - "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" -) - -type CommitOnchainConfig commit_store.CommitStoreDynamicConfig - -func (d CommitOnchainConfig) AbiString() string { - return ` - [ - { - "components": [ - {"name": "priceRegistry", "type": "address"} - ], - "type": "tuple" - } - ]` -} - -func (d CommitOnchainConfig) Validate() error { - if d.PriceRegistry == (common.Address{}) { - return errors.New("must set Price Registry address") - } - return nil -} - -type ExecOnchainConfig evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig - -func (d ExecOnchainConfig) AbiString() string { - return ` - [ - { - "components": [ - {"name": "permissionLessExecutionThresholdSeconds", "type": "uint32"}, - {"name": "router", "type": "address"}, - {"name": "priceRegistry", "type": "address"}, - {"name": "maxTokensLength", "type": "uint16"}, - {"name": "maxDataSize", "type": "uint32"} - ], - "type": "tuple" - } - ]` -} - -func (d ExecOnchainConfig) Validate() error { - if d.PermissionLessExecutionThresholdSeconds == 0 { - return errors.New("must set PermissionLessExecutionThresholdSeconds") - } - if d.Router == (common.Address{}) { - return errors.New("must set Router address") - } - if d.PriceRegistry == (common.Address{}) { - return errors.New("must set PriceRegistry address") - } - if d.MaxTokensLength == 0 { - return errors.New("must set MaxTokensLength") - } - if d.MaxDataSize == 0 { - return errors.New("must set MaxDataSize") - } - return nil -} - -func (d ExecOnchainConfig) PermissionLessExecutionThresholdDuration() time.Duration { - return time.Duration(d.PermissionLessExecutionThresholdSeconds) * time.Second -} diff --git a/core/services/ocr2/plugins/ccip/config/onchain_config_test.go b/core/services/ocr2/plugins/ccip/config/onchain_config_test.go deleted file mode 100644 index a13133f901..0000000000 --- a/core/services/ocr2/plugins/ccip/config/onchain_config_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package config - -import ( - "math/big" - "math/rand" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/require" - - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" -) - -func randomAddress() common.Address { - return common.BigToAddress(big.NewInt(rand.Int63())) -} - -func TestCommitOnchainConfig(t *testing.T) { - tests := []struct { - name string - want CommitOnchainConfig - expectErr bool - }{ - { - name: "encodes and decodes config with all fields set", - want: CommitOnchainConfig{ - PriceRegistry: randomAddress(), - }, - expectErr: false, - }, - { - name: "encodes and fails decoding config with missing fields", - want: CommitOnchainConfig{}, - expectErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - encoded, err := abihelpers.EncodeAbiStruct(tt.want) - require.NoError(t, err) - - decoded, err := abihelpers.DecodeAbiStruct[CommitOnchainConfig](encoded) - if tt.expectErr { - require.ErrorContains(t, err, "must set") - } else { - require.NoError(t, err) - require.Equal(t, tt.want, decoded) - } - }) - } -} - -func TestExecOnchainConfig(t *testing.T) { - tests := []struct { - name string - want ExecOnchainConfig - expectErr bool - }{ - { - name: "encodes and decodes config with all fields set", - want: ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: rand.Uint32(), - Router: randomAddress(), - PriceRegistry: randomAddress(), - MaxTokensLength: uint16(rand.Uint32()), - MaxDataSize: rand.Uint32(), - }, - }, - { - name: "encodes and fails decoding config with missing fields", - want: ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: rand.Uint32(), - MaxDataSize: rand.Uint32(), - }, - expectErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - encoded, err := abihelpers.EncodeAbiStruct(tt.want) - require.NoError(t, err) - - decoded, err := abihelpers.DecodeAbiStruct[ExecOnchainConfig](encoded) - if tt.expectErr { - require.ErrorContains(t, err, "must set") - } else { - require.NoError(t, err) - require.Equal(t, tt.want, decoded) - } - }) - } -} diff --git a/core/services/ocr2/plugins/ccip/config/type_and_version.go b/core/services/ocr2/plugins/ccip/config/type_and_version.go index 085b22fb23..c3519f6d38 100644 --- a/core/services/ocr2/plugins/ccip/config/type_and_version.go +++ b/core/services/ocr2/plugins/ccip/config/type_and_version.go @@ -17,25 +17,27 @@ var ( EVM2EVMOnRamp ContractType = "EVM2EVMOnRamp" EVM2EVMOffRamp ContractType = "EVM2EVMOffRamp" CommitStore ContractType = "CommitStore" + PriceRegistry ContractType = "PriceRegistry" ContractTypes = map[ContractType]struct{}{ EVM2EVMOffRamp: {}, EVM2EVMOnRamp: {}, CommitStore: {}, + PriceRegistry: {}, } ) -func VerifyTypeAndVersion(addr common.Address, client bind.ContractBackend, expectedType ContractType) error { - contractType, _, err := typeAndVersion(addr, client) +func VerifyTypeAndVersion(addr common.Address, client bind.ContractBackend, expectedType ContractType) (semver.Version, error) { + contractType, version, err := TypeAndVersion(addr, client) if err != nil { - return errors.Errorf("failed getting type and version %v", err) + return semver.Version{}, errors.Errorf("failed getting type and version %v", err) } if contractType != expectedType { - return errors.Errorf("Wrong contract type %s", contractType) + return semver.Version{}, errors.Errorf("Wrong contract type %s", contractType) } - return nil + return version, nil } -func typeAndVersion(addr common.Address, client bind.ContractBackend) (ContractType, semver.Version, error) { +func TypeAndVersion(addr common.Address, client bind.ContractBackend) (ContractType, semver.Version, error) { tv, err := type_and_version.NewTypeAndVersionInterface(addr, client) if err != nil { return "", semver.Version{}, err diff --git a/core/services/ocr2/plugins/ccip/execution_batch_building.go b/core/services/ocr2/plugins/ccip/execution_batch_building.go index b2be5a6f13..fea4faa361 100644 --- a/core/services/ocr2/plugins/ccip/execution_batch_building.go +++ b/core/services/ocr2/plugins/ccip/execution_batch_building.go @@ -3,15 +3,10 @@ package ccip import ( "context" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/merklemulti" @@ -19,15 +14,11 @@ import ( func getProofData( ctx context.Context, - lggr logger.Logger, - hashLeaf hashlib.LeafHasherInterface[[32]byte], - onRampAddress common.Address, - sourceReader ccipdata.Reader, - interval commit_store.CommitStoreInterval, -) (sendReqsInRoot []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], leaves [][32]byte, tree *merklemulti.Tree[[32]byte], err error) { + sourceReader ccipdata.OnRampReader, + interval ccipdata.CommitStoreInterval, +) (sendReqsInRoot []ccipdata.Event[internal.EVM2EVMMessage], leaves [][32]byte, tree *merklemulti.Tree[[32]byte], err error) { sendReqs, err := sourceReader.GetSendRequestsBetweenSeqNums( ctx, - onRampAddress, interval.Min, interval.Max, 0, // no need for confirmations, commitReport was already confirmed and we need all msgs in it @@ -35,9 +26,9 @@ func getProofData( if err != nil { return nil, nil, nil, err } - leaves, err = hashlib.LeavesFromIntervals(lggr, interval, hashLeaf, sendReqs) - if err != nil { - return nil, nil, nil, err + leaves = make([][32]byte, 0, len(sendReqs)) + for _, req := range sendReqs { + leaves = append(leaves, req.Data.Hash) } tree, err = merklemulti.NewTree(hashlib.NewKeccakCtx(), leaves) if err != nil { @@ -47,43 +38,44 @@ func getProofData( } func buildExecutionReportForMessages( - msgsInRoot []*evm_2_evm_offramp.InternalEVM2EVMMessage, + msgsInRoot []ccipdata.Event[internal.EVM2EVMMessage], leaves [][32]byte, tree *merklemulti.Tree[[32]byte], - commitInterval commit_store.CommitStoreInterval, + commitInterval ccipdata.CommitStoreInterval, observedMessages []ObservedMessage, -) (report evm_2_evm_offramp.InternalExecutionReport, hashes [][32]byte, err error) { +) (ccipdata.ExecReport, error) { innerIdxs := make([]int, 0, len(observedMessages)) - report.Messages = []evm_2_evm_offramp.InternalEVM2EVMMessage{} + var messages []internal.EVM2EVMMessage + var offchainTokenData [][][]byte for _, observedMessage := range observedMessages { if observedMessage.SeqNr < commitInterval.Min || observedMessage.SeqNr > commitInterval.Max { // We only return messages from a single root (the root of the first message). continue } innerIdx := int(observedMessage.SeqNr - commitInterval.Min) - report.Messages = append(report.Messages, *msgsInRoot[innerIdx]) - report.OffchainTokenData = append(report.OffchainTokenData, observedMessage.TokenData) - + messages = append(messages, msgsInRoot[innerIdx].Data) + offchainTokenData = append(offchainTokenData, observedMessage.TokenData) innerIdxs = append(innerIdxs, innerIdx) - hashes = append(hashes, leaves[innerIdx]) } merkleProof, err := tree.Prove(innerIdxs) if err != nil { - return evm_2_evm_offramp.InternalExecutionReport{}, nil, err + return ccipdata.ExecReport{}, err } // any capped proof will have length <= this one, so we reuse it to avoid proving inside loop, and update later if changed - report.Proofs = merkleProof.Hashes - report.ProofFlagBits = abihelpers.ProofFlagsToBits(merkleProof.SourceFlags) - - return report, hashes, nil + return ccipdata.ExecReport{ + Messages: messages, + Proofs: merkleProof.Hashes, + ProofFlagBits: abihelpers.ProofFlagsToBits(merkleProof.SourceFlags), + OffchainTokenData: offchainTokenData, + }, nil } // Validates the given message observations do not exceed the committed sequence numbers -// in the commitStore. -func validateSeqNumbers(serviceCtx context.Context, commitStore commit_store.CommitStoreInterface, observedMessages []ObservedMessage) error { - nextMin, err := commitStore.GetExpectedNextSequenceNumber(&bind.CallOpts{Context: serviceCtx}) +// in the commitStoreReader. +func validateSeqNumbers(serviceCtx context.Context, commitStore ccipdata.CommitStoreReader, observedMessages []ObservedMessage) error { + nextMin, err := commitStore.GetExpectedNextSequenceNumber(serviceCtx) if err != nil { return err } @@ -97,18 +89,18 @@ func validateSeqNumbers(serviceCtx context.Context, commitStore commit_store.Com } // Gets the commit report from the saved logs for a given sequence number. -func getCommitReportForSeqNum(ctx context.Context, destReader ccipdata.Reader, commitStore commit_store.CommitStoreInterface, seqNum uint64) (commit_store.CommitStoreCommitReport, error) { - acceptedReports, err := destReader.GetAcceptedCommitReportsGteSeqNum(ctx, commitStore.Address(), seqNum, 0) +func getCommitReportForSeqNum(ctx context.Context, commitStoreReader ccipdata.CommitStoreReader, seqNum uint64) (ccipdata.CommitStoreReport, error) { + acceptedReports, err := commitStoreReader.GetAcceptedCommitReportsGteSeqNum(ctx, seqNum, 0) if err != nil { - return commit_store.CommitStoreCommitReport{}, err + return ccipdata.CommitStoreReport{}, err } for _, acceptedReport := range acceptedReports { - reportInterval := acceptedReport.Data.Report.Interval + reportInterval := acceptedReport.Data.Interval if reportInterval.Min <= seqNum && seqNum <= reportInterval.Max { - return acceptedReport.Data.Report, nil + return acceptedReport.Data, nil } } - return commit_store.CommitStoreCommitReport{}, errors.Errorf("seq number not committed") + return ccipdata.CommitStoreReport{}, errors.Errorf("seq number not committed") } diff --git a/core/services/ocr2/plugins/ccip/execution_gas_helpers.go b/core/services/ocr2/plugins/ccip/execution_gas_helpers.go index 108684d4d6..de880e01bd 100644 --- a/core/services/ocr2/plugins/ccip/execution_gas_helpers.go +++ b/core/services/ocr2/plugins/ccip/execution_gas_helpers.go @@ -4,8 +4,6 @@ import ( "math" "math/big" "time" - - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" ) const ( @@ -28,6 +26,9 @@ const ( EXECUTION_STATE_PROCESSING_OVERHEAD_GAS = 2_100 + // COLD_SLOAD_COST for first reading the state 20_000 + // SSTORE_SET_GAS for writing from 0 (untouched) to non-zero (in-progress) 100 //# SLOAD_GAS = WARM_STORAGE_READ_COST for rewriting from non-zero (in-progress) to non-zero (success/failure) + EVM_MESSAGE_FIXED_BYTES = 448 // Byte size of fixed-size fields in EVM2EVMMessage + EVM_MESSAGE_BYTES_PER_TOKEN = 128 // Byte size of each token transfer, consisting of 1 EVMTokenAmount and 1 bytes, excl length of bytes + DA_MULTIPLIER_BASE = int64(10000) ) // return the size of bytes for msg tokens @@ -65,14 +66,6 @@ func maxGasOverHeadGas(numMsgs, dataLength, numTokens int) uint64 { return overheadGas(dataLength, numTokens) + merkleGasShare } -// computeExecCost calculates the costs for next execution, and converts to USD value scaled by 1e18 (e.g. 5$ = 5e18). -func computeExecCost(gasLimit *big.Int, execGasPriceEstimate, tokenPriceUSD *big.Int) *big.Int { - execGasEstimate := new(big.Int).Add(big.NewInt(FEE_BOOSTING_OVERHEAD_GAS), gasLimit) - execGasEstimate.Mul(execGasEstimate, execGasPriceEstimate) - - return ccipcalc.CalculateUsdPerUnitGas(execGasEstimate, tokenPriceUSD) -} - // waitBoostedFee boosts the given fee according to the time passed since the msg was sent. // RelativeBoostPerWaitHour is used to normalize the time diff, // it makes our loss taking "smooth" and gives us time to react without a hard deadline. diff --git a/core/services/ocr2/plugins/ccip/execution_gas_helpers_test.go b/core/services/ocr2/plugins/ccip/execution_gas_helpers_test.go index 5992db5962..0289a706d8 100644 --- a/core/services/ocr2/plugins/ccip/execution_gas_helpers_test.go +++ b/core/services/ocr2/plugins/ccip/execution_gas_helpers_test.go @@ -7,7 +7,6 @@ import ( "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestOverheadGas(t *testing.T) { @@ -69,45 +68,6 @@ func TestMaxGasOverHeadGas(t *testing.T) { } } -func TestComputeExecCost(t *testing.T) { - tests := []struct { - name string - gasLimit *big.Int - execGasEstimate *big.Int - tokenPriceUSD *big.Int - execCostUsd *big.Int - }{ - { - "happy flow", - big.NewInt(3_000_000), - big.NewInt(2e10), - big.NewInt(6e18), - big.NewInt(384e15), - }, - { - "low usd price", - big.NewInt(3_000_000), - big.NewInt(2e10), - big.NewInt(6e15), - big.NewInt(384e12), - }, - { - "zero token price", - big.NewInt(3_000_000), - big.NewInt(2e10), - big.NewInt(0), - big.NewInt(0), - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - execCostUsd := computeExecCost(tc.gasLimit, tc.execGasEstimate, tc.tokenPriceUSD) - require.Equal(t, tc.execCostUsd, execCostUsd) - }) - } -} - func TestWaitBoostedFee(t *testing.T) { tests := []struct { name string diff --git a/core/services/ocr2/plugins/ccip/execution_inflight.go b/core/services/ocr2/plugins/ccip/execution_inflight.go index dda3485674..6af24850dd 100644 --- a/core/services/ocr2/plugins/ccip/execution_inflight.go +++ b/core/services/ocr2/plugins/ccip/execution_inflight.go @@ -6,15 +6,15 @@ import ( "github.com/pkg/errors" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" ) // InflightInternalExecutionReport serves the same purpose as InflightCommitReport // see the comment on that struct for context. type InflightInternalExecutionReport struct { createdAt time.Time - messages []evm_2_evm_offramp.InternalEVM2EVMMessage + messages []internal.EVM2EVMMessage } // inflightExecReportsContainer holds existing inflight reports. @@ -62,7 +62,7 @@ func (container *inflightExecReportsContainer) expire(lggr logger.Logger) { container.reports = stillInFlight } -func (container *inflightExecReportsContainer) add(lggr logger.Logger, messages []evm_2_evm_offramp.InternalEVM2EVMMessage) error { +func (container *inflightExecReportsContainer) add(lggr logger.Logger, messages []internal.EVM2EVMMessage) error { container.locker.Lock() defer container.locker.Unlock() diff --git a/core/services/ocr2/plugins/ccip/execution_inflight_test.go b/core/services/ocr2/plugins/ccip/execution_inflight_test.go index cb7eddd9a3..470a5ba6fd 100644 --- a/core/services/ocr2/plugins/ccip/execution_inflight_test.go +++ b/core/services/ocr2/plugins/ccip/execution_inflight_test.go @@ -6,19 +6,19 @@ import ( "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" ) func TestInflightReportsContainer_add(t *testing.T) { lggr := logger.TestLogger(t) container := newInflightExecReportsContainer(time.Second) - err := container.add(lggr, []evm_2_evm_offramp.InternalEVM2EVMMessage{ + err := container.add(lggr, []internal.EVM2EVMMessage{ {SequenceNumber: 1}, {SequenceNumber: 2}, {SequenceNumber: 3}, }) require.NoError(t, err) - err = container.add(lggr, []evm_2_evm_offramp.InternalEVM2EVMMessage{ + err = container.add(lggr, []internal.EVM2EVMMessage{ {SequenceNumber: 1}, }) require.Error(t, err) @@ -30,7 +30,7 @@ func TestInflightReportsContainer_expire(t *testing.T) { lggr := logger.TestLogger(t) container := newInflightExecReportsContainer(time.Second) - err := container.add(lggr, []evm_2_evm_offramp.InternalEVM2EVMMessage{ + err := container.add(lggr, []internal.EVM2EVMMessage{ {SequenceNumber: 1}, {SequenceNumber: 2}, {SequenceNumber: 3}, }) require.NoError(t, err) diff --git a/core/services/ocr2/plugins/ccip/execution_plugin.go b/core/services/ocr2/plugins/ccip/execution_plugin.go index 95426bdd40..cc65ffa172 100644 --- a/core/services/ocr2/plugins/ccip/execution_plugin.go +++ b/core/services/ocr2/plugins/ccip/execution_plugin.go @@ -3,13 +3,12 @@ package ccip import ( "context" "encoding/json" - "fmt" "net/url" "strconv" + "github.com/Masterminds/semver/v3" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" chainselectors "github.com/smartcontractkit/chain-selectors" @@ -17,163 +16,159 @@ import ( relaylogger "github.com/smartcontractkit/chainlink-relay/pkg/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/contractutil" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/oraclelib" - "github.com/smartcontractkit/chainlink/v2/core/utils" - "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/logpoller" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/observability" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/contractutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/oraclelib" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/usdc" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/promwrapper" "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) -const ( - EXEC_CCIP_SENDS = "Exec ccip sends" - EXEC_REPORT_ACCEPTS = "Exec report accepts" - EXEC_EXECUTION_STATE_CHANGES = "Exec execution state changes" - EXEC_TOKEN_POOL_ADDED = "Token pool added" - EXEC_TOKEN_POOL_REMOVED = "Token pool removed" - FEE_TOKEN_ADDED = "Fee token added" - FEE_TOKEN_REMOVED = "Fee token removed" -) - -func NewExecutionServices(lggr logger.Logger, jb job.Job, chainSet evm.LegacyChainContainer, new bool, argsNoPlugin libocr2.OCR2OracleArgs, logError func(string), qopts ...pg.QOpt) ([]job.ServiceCtx, error) { +// TODO pass context? +func jobSpecToExecPluginConfig(lggr logger.Logger, jb job.Job, chainSet evm.LegacyChainContainer) (*ExecutionPluginStaticConfig, *BackfillArgs, error) { + if jb.OCR2OracleSpec == nil { + return nil, nil, errors.New("spec is nil") + } spec := jb.OCR2OracleSpec var pluginConfig ccipconfig.ExecutionPluginJobSpecConfig err := json.Unmarshal(spec.PluginConfig.Bytes(), &pluginConfig) if err != nil { - return nil, err + return nil, nil, err } - chainIDInterface, ok := spec.RelayConfig["chainID"] if !ok { - return nil, errors.New("chainID must be provided in relay config") + return nil, nil, errors.New("chainID must be provided in relay config") } destChainID := int64(chainIDInterface.(float64)) destChain, err := chainSet.Get(strconv.FormatInt(destChainID, 10)) if err != nil { - return nil, errors.Wrap(err, "get chainset") + return nil, nil, errors.Wrap(err, "get chainset") } - offRamp, err := contractutil.LoadOffRamp(common.HexToAddress(spec.ContractID), ExecPluginLabel, destChain.Client()) + offRamp, _, err := contractutil.LoadOffRamp(common.HexToAddress(spec.ContractID), ExecPluginLabel, destChain.Client()) if err != nil { - return nil, errors.Wrap(err, "failed loading offRamp") + return nil, nil, errors.Wrap(err, "failed loading offRamp") } offRampConfig, err := offRamp.GetStaticConfig(&bind.CallOpts{}) if err != nil { - return nil, err + return nil, nil, err } chainId, err := chainselectors.ChainIdFromSelector(offRampConfig.SourceChainSelector) if err != nil { - return nil, err + return nil, nil, err } sourceChain, err := chainSet.Get(strconv.FormatUint(chainId, 10)) if err != nil { - return nil, errors.Wrap(err, "unable to open source chain") - } - commitStore, err := contractutil.LoadCommitStore(offRampConfig.CommitStore, ExecPluginLabel, destChain.Client()) - if err != nil { - return nil, errors.Wrap(err, "failed loading commitStore") + return nil, nil, errors.Wrap(err, "unable to open source chain") } - onRamp, err := contractutil.LoadOnRamp(offRampConfig.OnRamp, ExecPluginLabel, sourceChain.Client()) + onRamp, onRampVersion, err := contractutil.LoadOnRamp(offRampConfig.OnRamp, ExecPluginLabel, sourceChain.Client()) if err != nil { - return nil, errors.Wrap(err, "failed loading onRamp") + return nil, nil, errors.Wrap(err, "failed loading onRamp") } - dynamicOnRampConfig, err := contractutil.LoadOnRampDynamicConfig(onRamp, sourceChain.Client()) + dynamicOnRampConfig, err := contractutil.LoadOnRampDynamicConfig(onRamp, onRampVersion, sourceChain.Client()) if err != nil { - return nil, errors.Wrap(err, "failed loading onRamp config") + return nil, nil, errors.Wrap(err, "failed loading onRamp config") } sourceRouter, err := router.NewRouter(dynamicOnRampConfig.Router, sourceChain.Client()) if err != nil { - return nil, errors.Wrap(err, "failed loading source router") + return nil, nil, errors.Wrap(err, "failed loading source router") } sourceWrappedNative, err := sourceRouter.GetWrappedNative(&bind.CallOpts{}) if err != nil { - return nil, errors.Wrap(err, "could not get source native token") + return nil, nil, errors.Wrap(err, "could not get source native token") } - sourcePriceRegistry, err := observability.NewObservedPriceRegistry(dynamicOnRampConfig.PriceRegistry, ExecPluginLabel, sourceChain.Client()) - if err != nil { - return nil, errors.Wrap(err, "could not create source price registry") - } - execLggr := lggr.Named("CCIPExecution").With( "sourceChain", ChainName(int64(chainId)), "destChain", ChainName(destChainID)) - - sourceChainEventClient := ccipdata.NewLogPollerReader(sourceChain.LogPoller(), execLggr, sourceChain.Client()) - - tokenDataProviders, err := getTokenDataProviders(lggr, pluginConfig, offRampConfig.OnRamp, sourceChainEventClient) + // TODO: we don't support onramp source registry changes without a reboot yet? + sourcePriceRegistry, err := ccipdata.NewPriceRegistryReader(lggr, dynamicOnRampConfig.PriceRegistry, sourceChain.LogPoller(), sourceChain.Client()) if err != nil { - return nil, errors.Wrap(err, "could not get token data providers") + return nil, nil, errors.Wrap(err, "could not load source registry") } - - wrappedPluginFactory := NewExecutionReportingPluginFactory( - ExecutionPluginConfig{ + offRampReader, err := ccipdata.NewOffRampReader(lggr, common.HexToAddress(spec.ContractID), destChain.Client(), destChain.LogPoller(), destChain.GasEstimator()) + if err != nil { + return nil, nil, errors.Wrap(err, "could not load offRampReader") + } + commitStoreReader, err := ccipdata.NewCommitStoreReader(lggr, offRampConfig.CommitStore, destChain.Client(), destChain.LogPoller(), destChain.GasEstimator()) + if err != nil { + return nil, nil, errors.Wrap(err, "could not load commitStoreReader reader") + } + onRampReader, err := ccipdata.NewOnRampReader(execLggr, offRampConfig.SourceChainSelector, + offRampConfig.ChainSelector, offRampConfig.OnRamp, sourceChain.LogPoller(), sourceChain.Client(), sourceChain.Config().EVM().FinalityTagEnabled()) + if err != nil { + return nil, nil, err + } + tokenDataProviders, err := getTokenDataProviders(lggr, pluginConfig, sourceChain.LogPoller()) + if err != nil { + return nil, nil, errors.Wrap(err, "could not get token data providers") + } + execLggr.Infow("Initialized exec plugin", + "pluginConfig", pluginConfig, + "onRampAddress", onRamp.Address(), + "sourcePriceRegistry", sourcePriceRegistry.Address(), + "dynamicOnRampConfig", dynamicOnRampConfig, + "sourceNative", sourceWrappedNative, + "sourceRouter", sourceRouter.Address()) + return &ExecutionPluginStaticConfig{ lggr: execLggr, sourceLP: sourceChain.LogPoller(), destLP: destChain.LogPoller(), - sourceReader: sourceChainEventClient, + onRampReader: onRampReader, destReader: ccipdata.NewLogPollerReader(destChain.LogPoller(), execLggr, destChain.Client()), - onRamp: onRamp, offRamp: offRamp, - commitStore: commitStore, + commitStoreReader: commitStoreReader, + offRampReader: offRampReader, sourcePriceRegistry: sourcePriceRegistry, sourceWrappedNativeToken: sourceWrappedNative, destClient: destChain.Client(), sourceClient: sourceChain.Client(), destGasEstimator: destChain.GasEstimator(), - leafHasher: hashlib.NewLeafHasher(offRampConfig.SourceChainSelector, offRampConfig.ChainSelector, onRamp.Address(), hashlib.NewKeccakCtx()), + destChainEVMID: destChain.ID(), tokenDataProviders: tokenDataProviders, - }) + }, &BackfillArgs{ + sourceLP: sourceChain.LogPoller(), + destLP: destChain.LogPoller(), + sourceStartBlock: pluginConfig.SourceStartBlock, + destStartBlock: pluginConfig.DestStartBlock, + }, nil +} - err = wrappedPluginFactory.UpdateLogPollerFilters(utils.ZeroAddress, qopts...) +func NewExecutionServices(lggr logger.Logger, jb job.Job, chainSet evm.LegacyChainContainer, new bool, argsNoPlugin libocr2.OCR2OracleArgs, logError func(string), qopts ...pg.QOpt) ([]job.ServiceCtx, error) { + execPluginConfig, backfillArgs, err := jobSpecToExecPluginConfig(lggr, jb, chainSet) if err != nil { return nil, err } + wrappedPluginFactory := NewExecutionReportingPluginFactory(*execPluginConfig) - argsNoPlugin.ReportingPluginFactory = promwrapper.NewPromFactory(wrappedPluginFactory, "CCIPExecution", spec.Relay, destChain.ID()) - argsNoPlugin.Logger = relaylogger.NewOCRWrapper(execLggr, true, logError) + argsNoPlugin.ReportingPluginFactory = promwrapper.NewPromFactory(wrappedPluginFactory, "CCIPExecution", jb.OCR2OracleSpec.Relay, execPluginConfig.destChainEVMID) + argsNoPlugin.Logger = relaylogger.NewOCRWrapper(execPluginConfig.lggr, true, logError) oracle, err := libocr2.NewOracle(argsNoPlugin) if err != nil { return nil, err } - execLggr.Infow("Initialized exec plugin", - "pluginConfig", pluginConfig, - "onRampAddress", onRamp.Address(), - "sourcePriceRegistry", sourcePriceRegistry.Address(), - "dynamicOnRampConfig", dynamicOnRampConfig, - "sourceNative", sourceWrappedNative, - "sourceRouter", sourceRouter.Address()) // If this is a brand-new job, then we make use of the start blocks. If not then we're rebooting and log poller will pick up where we left off. if new { return []job.ServiceCtx{ oraclelib.NewBackfilledOracle( - execLggr, - sourceChain.LogPoller(), - destChain.LogPoller(), - pluginConfig.SourceStartBlock, - pluginConfig.DestStartBlock, + execPluginConfig.lggr, + backfillArgs.sourceLP, + backfillArgs.destLP, + backfillArgs.sourceStartBlock, + backfillArgs.destStartBlock, job.NewServiceAdapter(oracle)), }, nil } return []job.ServiceCtx{job.NewServiceAdapter(oracle)}, nil } -func getTokenDataProviders(lggr logger.Logger, pluginConfig ccipconfig.ExecutionPluginJobSpecConfig, onRampAddress common.Address, sourceChainEventClient *ccipdata.LogPollerReader) (map[common.Address]tokendata.Reader, error) { +func getTokenDataProviders(lggr logger.Logger, pluginConfig ccipconfig.ExecutionPluginJobSpecConfig, sourceLP logpoller.LogPoller) (map[common.Address]tokendata.Reader, error) { tokenDataProviders := make(map[common.Address]tokendata.Reader) if pluginConfig.USDCConfig.AttestationAPI != "" { @@ -183,18 +178,19 @@ func getTokenDataProviders(lggr logger.Logger, pluginConfig ccipconfig.Execution return nil, err } - attestationURI, err2 := url.ParseRequestURI(pluginConfig.USDCConfig.AttestationAPI) - if err2 != nil { - return nil, errors.Wrap(err2, "failed to parse USDC attestation API") + attestationURI, err := url.ParseRequestURI(pluginConfig.USDCConfig.AttestationAPI) + if err != nil { + return nil, errors.Wrap(err, "failed to parse USDC attestation API") } + usdcReader, err := ccipdata.NewUSDCReader(lggr, pluginConfig.USDCConfig.SourceMessageTransmitterAddress, sourceLP) + if err != nil { + return nil, err + } tokenDataProviders[pluginConfig.USDCConfig.SourceTokenAddress] = tokendata.NewCachedReader( usdc.NewUSDCTokenDataReader( lggr, - sourceChainEventClient, - pluginConfig.USDCConfig.SourceTokenAddress, - pluginConfig.USDCConfig.SourceMessageTransmitterAddress, - onRampAddress, + usdcReader, attestationURI, ), ) @@ -203,173 +199,29 @@ func getTokenDataProviders(lggr logger.Logger, pluginConfig ccipconfig.Execution return tokenDataProviders, nil } -func getExecutionPluginSourceLpChainFilters(onRamp, priceRegistry common.Address, tokenDataProviders map[common.Address]tokendata.Reader) []logpoller.Filter { - var filters []logpoller.Filter - for _, provider := range tokenDataProviders { - filters = append(filters, provider.GetSourceLogPollerFilters()...) - } - - return append(filters, []logpoller.Filter{ - { - Name: logpoller.FilterName(EXEC_CCIP_SENDS, onRamp.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.SendRequested}, - Addresses: []common.Address{onRamp}, - }, - { - Name: logpoller.FilterName(FEE_TOKEN_ADDED, priceRegistry.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.FeeTokenAdded}, - Addresses: []common.Address{priceRegistry}, - }, - { - Name: logpoller.FilterName(FEE_TOKEN_REMOVED, priceRegistry.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.FeeTokenRemoved}, - Addresses: []common.Address{priceRegistry}, - }, - }...) -} - -func getExecutionPluginDestLpChainFilters(commitStore, offRamp, priceRegistry common.Address) []logpoller.Filter { - return []logpoller.Filter{ - { - Name: logpoller.FilterName(EXEC_REPORT_ACCEPTS, commitStore.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.ReportAccepted}, - Addresses: []common.Address{commitStore}, - }, - { - Name: logpoller.FilterName(EXEC_EXECUTION_STATE_CHANGES, offRamp.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.ExecutionStateChanged}, - Addresses: []common.Address{offRamp}, - }, - { - Name: logpoller.FilterName(EXEC_TOKEN_POOL_ADDED, offRamp.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.PoolAdded}, - Addresses: []common.Address{offRamp}, - }, - { - Name: logpoller.FilterName(EXEC_TOKEN_POOL_REMOVED, offRamp.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.PoolRemoved}, - Addresses: []common.Address{offRamp}, - }, - { - Name: logpoller.FilterName(FEE_TOKEN_ADDED, priceRegistry.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.FeeTokenAdded}, - Addresses: []common.Address{priceRegistry}, - }, - { - Name: logpoller.FilterName(FEE_TOKEN_REMOVED, priceRegistry.String()), - EventSigs: []common.Hash{abihelpers.EventSignatures.FeeTokenRemoved}, - Addresses: []common.Address{priceRegistry}, - }, - } -} - // UnregisterExecPluginLpFilters unregisters all the registered filters for both source and dest chains. -func UnregisterExecPluginLpFilters(ctx context.Context, lggr logger.Logger, spec *job.OCR2OracleSpec, chainSet evm.LegacyChainContainer, qopts ...pg.QOpt) error { - if spec == nil { - return errors.New("spec is nil") - } - - var pluginConfig ccipconfig.ExecutionPluginJobSpecConfig - err := json.Unmarshal(spec.PluginConfig.Bytes(), &pluginConfig) - if err != nil { - return err - } - - destChainIDInterface, ok := spec.RelayConfig["chainID"] - if !ok { - return errors.New("chainID must be provided in relay config") - } - destChainIDf64, is := destChainIDInterface.(float64) - if !is { - return fmt.Errorf("chain id '%v' is not float64", destChainIDInterface) - } - destChain, err := chainSet.Get(strconv.FormatInt(int64(destChainIDf64), 10)) - if err != nil { - return err - } - - offRampAddress := common.HexToAddress(spec.ContractID) - offRamp, err := contractutil.LoadOffRamp(offRampAddress, ExecPluginLabel, destChain.Client()) - if err != nil { - return err - } - - offRampConfig, err := offRamp.GetStaticConfig(&bind.CallOpts{}) - if err != nil { - return err - } - chainId, err := chainselectors.ChainIdFromSelector(offRampConfig.SourceChainSelector) +// See comment in UnregisterCommitPluginLpFilters +func UnregisterExecPluginLpFilters(ctx context.Context, lggr logger.Logger, jb job.Job, chainSet evm.LegacyChainContainer, qopts ...pg.QOpt) error { + execPluginConfig, _, err := jobSpecToExecPluginConfig(lggr, jb, chainSet) if err != nil { return err } - sourceChain, err := chainSet.Get(strconv.FormatUint(chainId, 10)) - if err != nil { - return errors.Wrap(err, "unable to open source chain") - } - sourceOnRamp, err := contractutil.LoadOnRamp(offRampConfig.OnRamp, ExecPluginLabel, sourceChain.Client()) - if err != nil { - return errors.Wrap(err, "failed loading onRamp") - } - - return unregisterExecutionPluginLpFilters(ctx, lggr, sourceChain.LogPoller(), destChain.LogPoller(), offRamp, offRampConfig, sourceOnRamp, sourceChain.Client(), pluginConfig, qopts...) -} - -func unregisterExecutionPluginLpFilters( - ctx context.Context, - lggr logger.Logger, - sourceLP logpoller.LogPoller, - destLP logpoller.LogPoller, - destOffRamp evm_2_evm_offramp.EVM2EVMOffRampInterface, - destOffRampConfig evm_2_evm_offramp.EVM2EVMOffRampStaticConfig, - sourceOnRamp evm_2_evm_onramp.EVM2EVMOnRampInterface, - sourceChainClient client.Client, - pluginConfig ccipconfig.ExecutionPluginJobSpecConfig, - qopts ...pg.QOpt) error { - destOffRampDynCfg, err := destOffRamp.GetDynamicConfig(&bind.CallOpts{Context: ctx}) - if err != nil { + if err := execPluginConfig.onRampReader.Close(qopts...); err != nil { return err } - - onRampDynCfg, err := contractutil.LoadOnRampDynamicConfig(sourceOnRamp, sourceChainClient) - if err != nil { - return err - } - - // SourceChainEventClient can be nil because it is not used in unregisterExecutionPluginLpFilters - tokenDataProviders, err := getTokenDataProviders(lggr, pluginConfig, destOffRampConfig.OnRamp, nil) - if err != nil { - return err + for _, tokenReader := range execPluginConfig.tokenDataProviders { + if err := tokenReader.Close(qopts...); err != nil { + return err + } } - - if err = logpollerutil.UnregisterLpFilters( - sourceLP, - getExecutionPluginSourceLpChainFilters(destOffRampConfig.OnRamp, onRampDynCfg.PriceRegistry, tokenDataProviders), - qopts..., - ); err != nil { + if err := execPluginConfig.offRampReader.Close(qopts...); err != nil { return err } - - return logpollerutil.UnregisterLpFilters( - destLP, - getExecutionPluginDestLpChainFilters(destOffRampConfig.CommitStore, destOffRamp.Address(), destOffRampDynCfg.PriceRegistry), - qopts..., - ) + return execPluginConfig.commitStoreReader.Close(qopts...) } // ExecutionReportToEthTxMeta generates a txmgr.EthTxMeta from the given report. // Only MessageIDs will be populated in the TxMeta. -func ExecutionReportToEthTxMeta(report []byte) (*txmgr.TxMeta, error) { - execReport, err := abihelpers.DecodeExecutionReport(report) - if err != nil { - return nil, err - } - - msgIDs := make([]string, len(execReport.Messages)) - for i, msg := range execReport.Messages { - msgIDs[i] = hexutil.Encode(msg.MessageId[:]) - } - - return &txmgr.TxMeta{ - MessageIDs: msgIDs, - }, nil +func ExecReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (func(report []byte) (*txmgr.TxMeta, error), error) { + return ccipdata.ExecReportToEthTxMeta(typ, ver) } diff --git a/core/services/ocr2/plugins/ccip/execution_plugin_test.go b/core/services/ocr2/plugins/ccip/execution_plugin_test.go index dec6e2f5ad..e870814c9d 100644 --- a/core/services/ocr2/plugins/ccip/execution_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/execution_plugin_test.go @@ -4,20 +4,11 @@ import ( "context" "testing" - "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" - mocklp "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/mocks" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/usdc" - "github.com/smartcontractkit/chainlink/v2/core/utils" ) func TestGetExecutionPluginFilterNamesFromSpec(t *testing.T) { @@ -57,7 +48,7 @@ func TestGetExecutionPluginFilterNamesFromSpec(t *testing.T) { for _, tc := range testCases { chainSet := &mocks.LegacyChainContainer{} t.Run(tc.description, func(t *testing.T) { - err := UnregisterExecPluginLpFilters(context.Background(), logger.TestLogger(t), tc.spec, chainSet) + err := UnregisterExecPluginLpFilters(context.Background(), logger.TestLogger(t), job.Job{OCR2OracleSpec: tc.spec}, chainSet) if tc.expectingErr { assert.Error(t, err) } else { @@ -66,67 +57,3 @@ func TestGetExecutionPluginFilterNamesFromSpec(t *testing.T) { }) } } - -func TestGetExecutionPluginFilterNames(t *testing.T) { - commitStoreAddr := common.HexToAddress("0xdafea492d9c6733ae3d56b7ed1adb60692c98bc3") - srcPriceRegAddr := common.HexToAddress("0xdafea492d9c6733ae3d56b7ed1adb60692c98bc9") - dstPriceRegAddr := common.HexToAddress("0xdafea492d9c6733ae3d56b7ed1adb60692c98b19") - - mockOffRamp, offRampAddr := testhelpers.NewFakeOffRamp(t) - mockOffRamp.SetDynamicConfig(evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig{PriceRegistry: dstPriceRegAddr}) - - mockOnRamp, onRampAddr := testhelpers.NewFakeOnRamp(t) - mockOnRamp.SetDynamicCfg(evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{PriceRegistry: srcPriceRegAddr}) - - pluginConfig := config.ExecutionPluginJobSpecConfig{ - USDCConfig: config.USDCConfig{ - SourceTokenAddress: utils.RandomAddress(), - SourceMessageTransmitterAddress: utils.RandomAddress(), - AttestationAPI: "http://localhost:8080", - }, - } - - srcLP := mocklp.NewLogPoller(t) - srcFilters := []string{ - "Exec ccip sends - " + onRampAddr.String(), - "Fee token added - 0xdAFea492D9c6733aE3d56B7ed1ADb60692c98bC9", - "Fee token removed - 0xdAFea492D9c6733aE3d56B7ed1ADb60692c98bC9", - usdc.MESSAGE_SENT_FILTER_NAME + " - " + pluginConfig.USDCConfig.SourceMessageTransmitterAddress.Hex(), - } - for _, f := range srcFilters { - srcLP.On("UnregisterFilter", f, mock.Anything).Return(nil) - } - - dstLP := mocklp.NewLogPoller(t) - dstFilters := []string{ - "Exec report accepts - 0xdafEa492d9C6733aE3D56b7eD1aDb60692c98bc3", - "Exec execution state changes - " + offRampAddr.String(), - "Token pool added - " + offRampAddr.String(), - "Token pool removed - " + offRampAddr.String(), - "Fee token added - 0xdaFEa492D9C6733Ae3D56b7ed1adB60692C98b19", - "Fee token removed - 0xdaFEa492D9C6733Ae3D56b7ed1adB60692C98b19", - } - for _, f := range dstFilters { - dstLP.On("UnregisterFilter", f, mock.Anything).Return(nil) - } - - err := unregisterExecutionPluginLpFilters( - context.Background(), - logger.TestLogger(t), - srcLP, - dstLP, - mockOffRamp, - evm_2_evm_offramp.EVM2EVMOffRampStaticConfig{ - CommitStore: commitStoreAddr, - OnRamp: onRampAddr, - SourceChainSelector: 5009297550715157269, - }, - mockOnRamp, - nil, - pluginConfig, - ) - assert.NoError(t, err) - - srcLP.AssertExpectations(t) - dstLP.AssertExpectations(t) -} diff --git a/core/services/ocr2/plugins/ccip/execution_reporting_plugin.go b/core/services/ocr2/plugins/ccip/execution_reporting_plugin.go index 01472c6a0c..75a6f26b8e 100644 --- a/core/services/ocr2/plugins/ccip/execution_reporting_plugin.go +++ b/core/services/ocr2/plugins/ccip/execution_reporting_plugin.go @@ -18,28 +18,19 @@ import ( "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "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" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/custom_token_pool" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/contractutil" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/observability" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" - "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) const ( @@ -55,101 +46,116 @@ var ( _ types.ReportingPlugin = &ExecutionReportingPlugin{} ) -type ExecutionPluginConfig struct { +type ExecutionPluginStaticConfig struct { lggr logger.Logger sourceLP, destLP logpoller.LogPoller - sourceReader ccipdata.Reader + onRampReader ccipdata.OnRampReader destReader ccipdata.Reader - onRamp evm_2_evm_onramp.EVM2EVMOnRampInterface + offRampReader ccipdata.OffRampReader offRamp evm_2_evm_offramp.EVM2EVMOffRampInterface - commitStore commit_store.CommitStoreInterface - sourcePriceRegistry price_registry.PriceRegistryInterface + commitStoreReader ccipdata.CommitStoreReader + sourcePriceRegistry ccipdata.PriceRegistryReader sourceWrappedNativeToken common.Address destClient evmclient.Client sourceClient evmclient.Client + destChainEVMID *big.Int destGasEstimator gas.EvmFeeEstimator - leafHasher hashlib.LeafHasherInterface[[32]byte] tokenDataProviders map[common.Address]tokendata.Reader } type ExecutionReportingPlugin struct { - config ExecutionPluginConfig + config ExecutionPluginStaticConfig + F int lggr logger.Logger inflightReports *inflightExecReportsContainer snoozedRoots cache.SnoozedRoots - destPriceRegistry price_registry.PriceRegistryInterface + destPriceRegistry ccipdata.PriceRegistryReader destWrappedNative common.Address - onchainConfig ccipconfig.ExecOnchainConfig - offchainConfig ccipconfig.ExecOffchainConfig + onchainConfig ccipdata.ExecOnchainConfig + offchainConfig ccipdata.ExecOffchainConfig cachedSourceFeeTokens cache.AutoSync[[]common.Address] cachedDestTokens cache.AutoSync[cache.CachedTokens] + cachedTokenPools cache.AutoSync[map[common.Address]common.Address] customTokenPoolFactory func(ctx context.Context, poolAddress common.Address, bind bind.ContractBackend) (custom_token_pool.CustomTokenPoolInterface, error) + gasPriceEstimator prices.GasPriceEstimatorExec } type ExecutionReportingPluginFactory struct { - config ExecutionPluginConfig + // Config derived from job specs and does not change between instances. + config ExecutionPluginStaticConfig - // We keep track of the registered filters - sourceChainFilters []logpoller.Filter - destChainFilters []logpoller.Filter - filtersMu *sync.Mutex + destPriceRegReader ccipdata.PriceRegistryReader + destPriceRegAddr common.Address + readersMu *sync.Mutex } -func NewExecutionReportingPluginFactory(config ExecutionPluginConfig) *ExecutionReportingPluginFactory { +func NewExecutionReportingPluginFactory(config ExecutionPluginStaticConfig) *ExecutionReportingPluginFactory { return &ExecutionReportingPluginFactory{ config: config, - filtersMu: &sync.Mutex{}, + readersMu: &sync.Mutex{}, } } -func (rf *ExecutionReportingPluginFactory) NewReportingPlugin(config types.ReportingPluginConfig) (types.ReportingPlugin, types.ReportingPluginInfo, error) { - onchainConfig, err := abihelpers.DecodeAbiStruct[ccipconfig.ExecOnchainConfig](config.OnchainConfig) - if err != nil { - return nil, types.ReportingPluginInfo{}, err +func (rf *ExecutionReportingPluginFactory) UpdateDynamicReaders(newPriceRegAddr common.Address) error { + rf.readersMu.Lock() + defer rf.readersMu.Unlock() + // TODO: Investigate use of Close() to cleanup. + // TODO: a true price registry upgrade on an existing lane may want some kind of start block in its config? Right now we + // essentially assume that plugins don't care about historical price reg logs. + if rf.destPriceRegAddr == newPriceRegAddr { + // No-op + return nil } - offchainConfig, err := ccipconfig.DecodeOffchainConfig[ccipconfig.ExecOffchainConfig](config.OffchainConfig) - if err != nil { - return nil, types.ReportingPluginInfo{}, err + // Close old reader (if present) and open new reader if address changed. + if rf.destPriceRegReader != nil { + if err := rf.destPriceRegReader.Close(); err != nil { + return err + } } - priceRegistry, err := observability.NewObservedPriceRegistry(onchainConfig.PriceRegistry, ExecPluginLabel, rf.config.destClient) + destPriceRegistryReader, err := ccipdata.NewPriceRegistryReader(rf.config.lggr, newPriceRegAddr, rf.config.destLP, rf.config.destClient) if err != nil { - return nil, types.ReportingPluginInfo{}, err + return err } - destRouter, err := router.NewRouter(onchainConfig.Router, rf.config.destClient) + rf.destPriceRegReader = destPriceRegistryReader + rf.destPriceRegAddr = newPriceRegAddr + return nil +} + +func (rf *ExecutionReportingPluginFactory) NewReportingPlugin(config types.ReportingPluginConfig) (types.ReportingPlugin, types.ReportingPluginInfo, error) { + destPriceRegistry, destWrappedNative, err := rf.config.offRampReader.ChangeConfig(config.OnchainConfig, config.OffchainConfig) if err != nil { return nil, types.ReportingPluginInfo{}, err } - destWrappedNative, err := destRouter.GetWrappedNative(nil) + // Open dynamic readers + err = rf.UpdateDynamicReaders(destPriceRegistry) if err != nil { return nil, types.ReportingPluginInfo{}, err } - if err = rf.UpdateLogPollerFilters(onchainConfig.PriceRegistry); err != nil { - return nil, types.ReportingPluginInfo{}, err - } - + offchainConfig := rf.config.offRampReader.OffchainConfig() cachedSourceFeeTokens := cache.NewCachedFeeTokens(rf.config.sourceLP, rf.config.sourcePriceRegistry, int64(offchainConfig.SourceFinalityDepth)) - cachedDestTokens := cache.NewCachedSupportedTokens(rf.config.destLP, rf.config.offRamp, priceRegistry, int64(offchainConfig.DestOptimisticConfirmations)) - rf.config.lggr.Infow("Starting exec plugin", - "offchainConfig", offchainConfig, - "onchainConfig", onchainConfig) + cachedDestTokens := cache.NewCachedSupportedTokens(rf.config.destLP, rf.config.offRampReader, rf.destPriceRegReader, int64(offchainConfig.DestOptimisticConfirmations)) + + cachedTokenPools := cache.NewTokenPools(rf.config.lggr, rf.config.destLP, rf.config.offRampReader, int64(offchainConfig.DestOptimisticConfirmations), 5) return &ExecutionReportingPlugin{ config: rf.config, F: config.F, lggr: rf.config.lggr.Named("ExecutionReportingPlugin"), - snoozedRoots: cache.NewSnoozedRoots(onchainConfig.PermissionLessExecutionThresholdDuration(), offchainConfig.RootSnoozeTime.Duration()), + snoozedRoots: cache.NewSnoozedRoots(rf.config.offRampReader.OnchainConfig().PermissionLessExecutionThresholdSeconds, offchainConfig.RootSnoozeTime.Duration()), inflightReports: newInflightExecReportsContainer(offchainConfig.InflightCacheExpiry.Duration()), - destPriceRegistry: priceRegistry, + destPriceRegistry: rf.destPriceRegReader, destWrappedNative: destWrappedNative, - onchainConfig: onchainConfig, + onchainConfig: rf.config.offRampReader.OnchainConfig(), offchainConfig: offchainConfig, cachedDestTokens: cachedDestTokens, cachedSourceFeeTokens: cachedSourceFeeTokens, + cachedTokenPools: cachedTokenPools, customTokenPoolFactory: func(ctx context.Context, poolAddress common.Address, contractBackend bind.ContractBackend) (custom_token_pool.CustomTokenPoolInterface, error) { return custom_token_pool.NewCustomTokenPool(poolAddress, contractBackend) }, + gasPriceEstimator: rf.config.offRampReader.GasPriceEstimator(), }, types.ReportingPluginInfo{ Name: "CCIPExecution", // Setting this to false saves on calldata since OffRamp doesn't require agreement between NOPs @@ -168,7 +174,11 @@ func (r *ExecutionReportingPlugin) Query(context.Context, types.ReportTimestamp) func (r *ExecutionReportingPlugin) Observation(ctx context.Context, timestamp types.ReportTimestamp, query types.Query) (types.Observation, error) { lggr := r.lggr.Named("ExecutionObservation") - if contractutil.IsCommitStoreDownNow(ctx, lggr, r.config.commitStore) { + down, err := r.config.commitStoreReader.IsDown(ctx) + if err != nil { + return nil, errors.Wrap(err, "isDown check errored") + } + if down { return nil, ErrCommitStoreIsDown } // Expire any inflight reports. @@ -201,47 +211,11 @@ func (r *ExecutionReportingPlugin) Observation(ctx context.Context, timestamp ty return NewExecutionObservation(executableObservations).Marshal() } -// UpdateLogPollerFilters updates the log poller filters for the source and destination chains. -// pass zeroAddress if dstPriceRegistry is unknown, filters with zero address are omitted. -func (rf *ExecutionReportingPluginFactory) UpdateLogPollerFilters(destPriceRegistry common.Address, qopts ...pg.QOpt) error { - rf.filtersMu.Lock() - defer rf.filtersMu.Unlock() - - // source chain filters - sourceFiltersBefore, sourceFiltersNow := rf.sourceChainFilters, getExecutionPluginSourceLpChainFilters( - rf.config.onRamp.Address(), - rf.config.sourcePriceRegistry.Address(), - rf.config.tokenDataProviders, - ) - created, deleted := logpollerutil.FiltersDiff(sourceFiltersBefore, sourceFiltersNow) - if err := logpollerutil.UnregisterLpFilters(rf.config.sourceLP, deleted, qopts...); err != nil { - return err - } - if err := logpollerutil.RegisterLpFilters(rf.config.sourceLP, created, qopts...); err != nil { - return err - } - rf.sourceChainFilters = sourceFiltersNow - - // destination chain filters - destFiltersBefore, destFiltersNow := rf.destChainFilters, getExecutionPluginDestLpChainFilters(rf.config.commitStore.Address(), rf.config.offRamp.Address(), destPriceRegistry) - created, deleted = logpollerutil.FiltersDiff(destFiltersBefore, destFiltersNow) - if err := logpollerutil.UnregisterLpFilters(rf.config.destLP, deleted, qopts...); err != nil { - return err - } - if err := logpollerutil.RegisterLpFilters(rf.config.destLP, created, qopts...); err != nil { - return err - } - rf.destChainFilters = destFiltersNow - - return nil -} - func (r *ExecutionReportingPlugin) getExecutableObservations(ctx context.Context, lggr logger.Logger, timestamp types.ReportTimestamp, inflight []InflightInternalExecutionReport) ([]ObservedMessage, error) { unexpiredReports, err := getUnexpiredCommitReports( ctx, - r.config.destReader, - r.config.commitStore, - r.onchainConfig.PermissionLessExecutionThresholdDuration(), + r.config.commitStoreReader, + r.onchainConfig.PermissionLessExecutionThresholdSeconds, ) if err != nil { return nil, err @@ -277,8 +251,8 @@ func (r *ExecutionReportingPlugin) getExecutableObservations(ctx context.Context } return getTokensPrices(ctx, dstTokens.FeeTokens, r.destPriceRegistry, append(supportedDestTokens, r.destWrappedNative)) }) - getDestGasPrice := cache.LazyFetch(func() (*big.Int, error) { - return r.estimateDestinationGasPrice(ctx) + getDestGasPrice := cache.LazyFetch(func() (prices.GasPrice, error) { + return r.gasPriceEstimator.GetGasPrice(ctx) }) lggr.Infow("Processing unexpired reports", "n", len(unexpiredReports)) @@ -329,7 +303,7 @@ func (r *ExecutionReportingPlugin) getExecutableObservations(ctx context.Context continue } - blessed, err := r.config.commitStore.IsBlessed(&bind.CallOpts{Context: ctx}, merkleRoot) + blessed, err := r.config.commitStoreReader.IsBlessed(ctx, merkleRoot) if err != nil { return nil, err } @@ -395,12 +369,17 @@ func (r *ExecutionReportingPlugin) destPoolRateLimits(ctx context.Context, commi } } + tokenPools, err := r.cachedTokenPools.Get(ctx) + if err != nil { + return nil, fmt.Errorf("get cached token pools: %w", err) + } + res := make(map[common.Address]*big.Int, len(dstTokens)) for dstToken := range dstTokens { - poolAddress, err := r.config.offRamp.GetPoolByDestToken(&bind.CallOpts{Context: ctx}, dstToken) - if err != nil { - return nil, fmt.Errorf("get pool by dest token (%s): %w", dstToken, err) + poolAddress, exists := tokenPools[dstToken] + if !exists { + return nil, fmt.Errorf("pool for token '%s' does not exist", dstToken) } tokenPool, err := r.customTokenPoolFactory(ctx, poolAddress, r.config.destClient) @@ -421,18 +400,6 @@ func (r *ExecutionReportingPlugin) destPoolRateLimits(ctx context.Context, commi return res, nil } -func (r *ExecutionReportingPlugin) estimateDestinationGasPrice(ctx context.Context) (*big.Int, error) { - destGasPriceWei, _, err := r.config.destGasEstimator.GetFee(ctx, nil, 0, assets.NewWei(big.NewInt(int64(r.offchainConfig.MaxGasPrice)))) - if err != nil { - return nil, errors.Wrap(err, "could not estimate destination gas price") - } - destGasPrice := destGasPriceWei.Legacy.ToInt() - if destGasPriceWei.DynamicFeeCap != nil { - destGasPrice = destGasPriceWei.DynamicFeeCap.ToInt() - } - return destGasPrice, nil -} - func (r *ExecutionReportingPlugin) sourceDestinationTokens(ctx context.Context) (map[common.Address]common.Address, []common.Address, error) { destTokens, err := r.cachedDestTokens.Get(ctx) if err != nil { @@ -451,9 +418,8 @@ func (r *ExecutionReportingPlugin) sourceDestinationTokens(ctx context.Context) // before. It doesn't matter if the executed succeeded, since we don't retry previous // attempts even if they failed. Value in the map indicates whether the log is finalized or not. func (r *ExecutionReportingPlugin) getExecutedSeqNrsInRange(ctx context.Context, min, max uint64, latestBlock int64) (map[uint64]bool, error) { - stateChanges, err := r.config.destReader.GetExecutionStateChangesBetweenSeqNums( + stateChanges, err := r.config.offRampReader.GetExecutionStateChangesBetweenSeqNums( ctx, - r.config.offRamp.Address(), min, max, int(r.offchainConfig.DestOptimisticConfirmations), @@ -480,7 +446,7 @@ func (r *ExecutionReportingPlugin) buildBatch( aggregateTokenLimit *big.Int, sourceTokenPricesUSD map[common.Address]*big.Int, destTokenPricesUSD map[common.Address]*big.Int, - execGasPriceEstimate cache.LazyFunction[*big.Int], + gasPriceEstimate cache.LazyFunction[prices.GasPrice], sourceToDestToken map[common.Address]common.Address, destTokenPoolRateLimits map[common.Address]*big.Int, ) (executableMessages []ObservedMessage) { @@ -553,7 +519,7 @@ func (r *ExecutionReportingPlugin) buildBatch( } // Fee boosting - execGasPriceEstimateValue, err := execGasPriceEstimate() + gasPriceValue, err := gasPriceEstimate() if err != nil { msgLggr.Errorw("Unexpected error fetching gas price estimate", "err", err) return []ObservedMessage{} @@ -565,7 +531,12 @@ func (r *ExecutionReportingPlugin) buildBatch( continue } - execCostUsd := computeExecCost(msg.GasLimit, execGasPriceEstimateValue, dstWrappedNativePrice) + execCostUsd, err := r.gasPriceEstimator.EstimateMsgCostUSD(gasPriceValue, dstWrappedNativePrice, msg) + if err != nil { + msgLggr.Errorw("failed to estimate message cost USD", "err", err) + return []ObservedMessage{} + } + // calculating the source chain fee, dividing by 1e18 for denomination. // For example: // FeeToken=link; FeeTokenAmount=1e17 i.e. 0.1 link, price is 6e18 USD/link (1 USD = 1e18), @@ -659,7 +630,7 @@ func getTokenData(ctx context.Context, lggr logger.Logger, msg internal.EVM2EVMO func (r *ExecutionReportingPlugin) isRateLimitEnoughForTokenPool( destTokenPoolRateLimits map[common.Address]*big.Int, - sourceTokenAmounts []evm_2_evm_offramp.ClientEVMTokenAmount, + sourceTokenAmounts []internal.TokenAmount, inflightTokenAmounts map[common.Address]*big.Int, sourceToDestToken map[common.Address]common.Address, ) bool { @@ -723,7 +694,7 @@ func calculateMessageMaxGas(gasLimit *big.Int, numRequests, dataLen, numTokens i // helper struct to hold the commitReport and the related send requests type commitReportWithSendRequests struct { - commitReport commit_store.CommitStoreCommitReport + commitReport ccipdata.CommitStoreReport sendRequestsWithMeta []internal.EVM2EVMOnRampCCIPSendRequestedWithMeta } @@ -755,7 +726,7 @@ func (r *commitReportWithSendRequests) sendReqFits(sendReq internal.EVM2EVMOnRam // getReportsWithSendRequests returns the target reports with populated send requests. func (r *ExecutionReportingPlugin) getReportsWithSendRequests( ctx context.Context, - reports []commit_store.CommitStoreCommitReport, + reports []ccipdata.CommitStoreReport, ) ([]commitReportWithSendRequests, error) { if len(reports) == 0 { return nil, nil @@ -776,11 +747,10 @@ func (r *ExecutionReportingPlugin) getReportsWithSendRequests( // use errgroup to fetch send request logs and executed sequence numbers in parallel eg := &errgroup.Group{} - var sendRequests []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested] + var sendRequests []ccipdata.Event[internal.EVM2EVMMessage] eg.Go(func() error { - sendReqs, err := r.config.sourceReader.GetSendRequestsBetweenSeqNums( + sendReqs, err := r.config.onRampReader.GetSendRequestsBetweenSeqNums( ctx, - r.config.onRamp.Address(), intervalMin, intervalMax, int(r.offchainConfig.SourceFinalityDepth), @@ -821,19 +791,17 @@ func (r *ExecutionReportingPlugin) getReportsWithSendRequests( } for _, sendReq := range sendRequests { - msg := abihelpers.OnRampMessageToOffRampMessage(sendReq.Data.Message) - // if value exists in the map then it's executed // if value exists, and it's true then it's considered finalized - finalized, executed := executedSeqNums[msg.SequenceNumber] + finalized, executed := executedSeqNums[sendReq.Data.SequenceNumber] reqWithMeta := internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ - InternalEVM2EVMMessage: msg, - BlockTimestamp: sendReq.BlockTimestamp, - Executed: executed, - Finalized: finalized, - LogIndex: sendReq.Data.Raw.Index, - TxHash: sendReq.Data.Raw.TxHash, + EVM2EVMMessage: sendReq.Data, + BlockTimestamp: sendReq.BlockTimestamp, + Executed: executed, + Finalized: finalized, + LogIndex: sendReq.LogIndex, + TxHash: sendReq.TxHash, } // attach the msg to the appropriate reports @@ -847,7 +815,7 @@ func (r *ExecutionReportingPlugin) getReportsWithSendRequests( return reportsWithSendReqs, nil } -func aggregateTokenValue(destTokenPricesUSD map[common.Address]*big.Int, sourceToDest map[common.Address]common.Address, tokensAndAmount []evm_2_evm_offramp.ClientEVMTokenAmount) (*big.Int, error) { +func aggregateTokenValue(destTokenPricesUSD map[common.Address]*big.Int, sourceToDest map[common.Address]common.Address, tokensAndAmount []internal.TokenAmount) (*big.Int, error) { sum := big.NewInt(0) for i := 0; i < len(tokensAndAmount); i++ { price, ok := destTokenPricesUSD[sourceToDest[tokensAndAmount[i].Token]] @@ -862,37 +830,30 @@ func aggregateTokenValue(destTokenPricesUSD map[common.Address]*big.Int, sourceT // Assumes non-empty report. Messages to execute can span more than one report, but are assumed to be in order of increasing // sequence number. func (r *ExecutionReportingPlugin) buildReport(ctx context.Context, lggr logger.Logger, observedMessages []ObservedMessage) ([]byte, error) { - if err := validateSeqNumbers(ctx, r.config.commitStore, observedMessages); err != nil { + if err := validateSeqNumbers(ctx, r.config.commitStoreReader, observedMessages); err != nil { return nil, err } - commitReport, err := getCommitReportForSeqNum(ctx, r.config.destReader, r.config.commitStore, observedMessages[0].SeqNr) + commitReport, err := getCommitReportForSeqNum(ctx, r.config.commitStoreReader, observedMessages[0].SeqNr) if err != nil { return nil, err } lggr.Infow("Building execution report", "observations", observedMessages, "merkleRoot", hexutil.Encode(commitReport.MerkleRoot[:]), "report", commitReport) - sendReqsInRoot, leaves, tree, err := getProofData(ctx, lggr, r.config.leafHasher, r.config.onRamp.Address(), r.config.sourceReader, commitReport.Interval) + sendReqsInRoot, leaves, tree, err := getProofData(ctx, r.config.onRampReader, commitReport.Interval) if err != nil { return nil, err } - messages := make([]*evm_2_evm_offramp.InternalEVM2EVMMessage, len(sendReqsInRoot)) - for i, msg := range sendReqsInRoot { - offRampMsg := abihelpers.OnRampMessageToOffRampMessage(msg.Data.Message) - messages[i] = &offRampMsg - } - // cap messages which fits MaxExecutionReportLength (after serialized) capped := sort.Search(len(observedMessages), func(i int) bool { - report, _, err2 := buildExecutionReportForMessages(messages, leaves, tree, commitReport.Interval, observedMessages[:i+1]) + report, err2 := buildExecutionReportForMessages(sendReqsInRoot, leaves, tree, commitReport.Interval, observedMessages[:i+1]) if err2 != nil { r.lggr.Errorw("build execution report", "err", err2) return false } - var encoded []byte - encoded, err = abihelpers.EncodeExecutionReport(report) - if err != nil { + encoded, err2 := r.config.offRampReader.EncodeExecutionReport(report) + if err2 != nil { // false makes Search keep looking to the right, always including any "erroring" ObservedMessage and allowing us to detect in the bottom return false } @@ -902,12 +863,12 @@ func (r *ExecutionReportingPlugin) buildReport(ctx context.Context, lggr logger. return nil, err } - execReport, hashes, err := buildExecutionReportForMessages(messages, leaves, tree, commitReport.Interval, observedMessages[:capped]) + execReport, err := buildExecutionReportForMessages(sendReqsInRoot, leaves, tree, commitReport.Interval, observedMessages[:capped]) if err != nil { return nil, err } - encodedReport, err := abihelpers.EncodeExecutionReport(execReport) + encodedReport, err := r.config.offRampReader.EncodeExecutionReport(execReport) if err != nil { return nil, err } @@ -918,17 +879,12 @@ func (r *ExecutionReportingPlugin) buildReport(ctx context.Context, lggr logger. len(observedMessages), capped, len(encodedReport), MaxExecutionReportLength, ) } - // Double check this verifies before sending. - res, err := r.config.commitStore.Verify(&bind.CallOpts{Context: ctx}, hashes, execReport.Proofs, execReport.ProofFlagBits) + valid, err := r.config.commitStoreReader.VerifyExecutionReport(ctx, execReport) if err != nil { - lggr.Errorw("Unable to call verify", "observations", observedMessages[:capped], "root", commitReport.MerkleRoot[:], "seqRange", commitReport.Interval, "err", err) - return nil, err + return nil, errors.Wrap(err, "unable to verify") } - // No timestamp, means failed to verify root. - if res.Cmp(big.NewInt(0)) == 0 { - root := tree.Root() - lggr.Errorf("Root does not verify for messages: %v, our inner root 0x%x", observedMessages[:capped], root) + if !valid { return nil, errors.New("root does not verify") } return encodedReport, nil @@ -1021,15 +977,15 @@ func calculateObservedMessagesConsensus(observations []ExecutionObservation, f i func (r *ExecutionReportingPlugin) ShouldAcceptFinalizedReport(ctx context.Context, timestamp types.ReportTimestamp, report types.Report) (bool, error) { lggr := r.lggr.Named("ShouldAcceptFinalizedReport") - messages, err := abihelpers.MessagesFromExecutionReport(report) + execReport, err := r.config.offRampReader.DecodeExecutionReport(report) if err != nil { lggr.Errorw("Unable to decode report", "err", err) return false, err } - lggr = lggr.With("messageIDs", contractutil.GetMessageIDsAsHexString(messages)) + lggr = lggr.With("messageIDs", contractutil.GetMessageIDsAsHexString(execReport.Messages)) // If the first message is executed already, this execution report is stale, and we do not accept it. - stale, err := r.isStaleReport(messages) + stale, err := r.isStaleReport(execReport.Messages) if err != nil { return false, err } @@ -1038,7 +994,7 @@ func (r *ExecutionReportingPlugin) ShouldAcceptFinalizedReport(ctx context.Conte return false, nil } // Else just assume in flight - if err = r.inflightReports.add(lggr, messages); err != nil { + if err = r.inflightReports.add(lggr, execReport.Messages); err != nil { return false, err } lggr.Info("Accepting finalized report") @@ -1047,17 +1003,17 @@ func (r *ExecutionReportingPlugin) ShouldAcceptFinalizedReport(ctx context.Conte func (r *ExecutionReportingPlugin) ShouldTransmitAcceptedReport(ctx context.Context, timestamp types.ReportTimestamp, report types.Report) (bool, error) { lggr := r.lggr.Named("ShouldTransmitAcceptedReport") - messages, err := abihelpers.MessagesFromExecutionReport(report) + execReport, err := r.config.offRampReader.DecodeExecutionReport(report) if err != nil { lggr.Errorw("Unable to decode report", "err", err) return false, nil } - lggr = lggr.With("messageIDs", contractutil.GetMessageIDsAsHexString(messages)) + lggr = lggr.With("messageIDs", contractutil.GetMessageIDsAsHexString(execReport.Messages)) // If report is not stale we transmit. // When the executeTransmitter enqueues the tx for tx manager, // we mark it as execution_sent, removing it from the set of inflight messages. - stale, err := r.isStaleReport(messages) + stale, err := r.isStaleReport(execReport.Messages) if err != nil { return false, err } @@ -1070,7 +1026,7 @@ func (r *ExecutionReportingPlugin) ShouldTransmitAcceptedReport(ctx context.Cont return true, err } -func (r *ExecutionReportingPlugin) isStaleReport(messages []evm_2_evm_offramp.InternalEVM2EVMMessage) (bool, error) { +func (r *ExecutionReportingPlugin) isStaleReport(messages []internal.EVM2EVMMessage) (bool, error) { if len(messages) == 0 { return true, fmt.Errorf("messages are empty") } @@ -1082,7 +1038,7 @@ func (r *ExecutionReportingPlugin) isStaleReport(messages []evm_2_evm_offramp.In if err != nil { return true, err } - if state := abihelpers.MessageExecutionState(msgState); state == abihelpers.ExecutionStateFailure || state == abihelpers.ExecutionStateSuccess { + if state := ccipdata.MessageExecutionState(msgState); state == ccipdata.ExecutionStateFailure || state == ccipdata.ExecutionStateSuccess { return true, nil } @@ -1132,12 +1088,12 @@ func inflightAggregates( // results include feeTokens and passed-in tokens // price values are USD per 1e18 of smallest token denomination, in base units 1e18 (e.g. 5$ = 5e18 USD per 1e18 units). // this function is used for price registry of both source and destination chains. -func getTokensPrices(ctx context.Context, feeTokens []common.Address, priceRegistry price_registry.PriceRegistryInterface, tokens []common.Address) (map[common.Address]*big.Int, error) { +func getTokensPrices(ctx context.Context, feeTokens []common.Address, priceRegistry ccipdata.PriceRegistryReader, tokens []common.Address) (map[common.Address]*big.Int, error) { priceRegistryAddress := priceRegistry.Address() prices := make(map[common.Address]*big.Int) wantedTokens := append(feeTokens, tokens...) - fetchedPrices, err := priceRegistry.GetTokenPrices(&bind.CallOpts{Context: ctx}, wantedTokens) + fetchedPrices, err := priceRegistry.GetTokenPrices(ctx, wantedTokens) if err != nil { return nil, errors.Wrapf(err, "could not get token prices of %v", wantedTokens) } @@ -1168,13 +1124,11 @@ func getTokensPrices(ctx context.Context, feeTokens []common.Address, priceRegis func getUnexpiredCommitReports( ctx context.Context, - destReader ccipdata.Reader, - commitStore commit_store.CommitStoreInterface, + commitStoreReader ccipdata.CommitStoreReader, permissionExecutionThreshold time.Duration, -) ([]commit_store.CommitStoreCommitReport, error) { - acceptedReports, err := destReader.GetAcceptedCommitReportsGteTimestamp( +) ([]ccipdata.CommitStoreReport, error) { + acceptedReports, err := commitStoreReader.GetAcceptedCommitReportsGteTimestamp( ctx, - commitStore.Address(), time.Now().Add(-permissionExecutionThreshold), 0, ) @@ -1182,9 +1136,9 @@ func getUnexpiredCommitReports( return nil, err } - var reports []commit_store.CommitStoreCommitReport + var reports []ccipdata.CommitStoreReport for _, acceptedReport := range acceptedReports { - reports = append(reports, acceptedReport.Data.Report) + reports = append(reports, acceptedReport.Data) } return reports, nil } diff --git a/core/services/ocr2/plugins/ccip/execution_reporting_plugin_test.go b/core/services/ocr2/plugins/ccip/execution_reporting_plugin_test.go index 18e1db63fc..38c5d9b16c 100644 --- a/core/services/ocr2/plugins/ccip/execution_reporting_plugin_test.go +++ b/core/services/ocr2/plugins/ccip/execution_reporting_plugin_test.go @@ -4,12 +4,10 @@ import ( "bytes" "context" "encoding/json" - "fmt" "math" "math/big" "reflect" "sort" - "sync" "testing" "time" @@ -24,26 +22,17 @@ import ( "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/gas" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/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/gethwrappers/ccip/generated/custom_token_pool" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" mock_contracts "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/mocks" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/cache" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" "github.com/smartcontractkit/chainlink/v2/core/utils" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -54,9 +43,10 @@ func TestExecutionReportingPlugin_Observation(t *testing.T) { name string commitStorePaused bool inflightReports []InflightInternalExecutionReport - unexpiredReports []ccipdata.Event[commit_store.CommitStoreReportAccepted] - sendRequests []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested] + unexpiredReports []ccipdata.Event[ccipdata.CommitStoreReport] + sendRequests []ccipdata.Event[internal.EVM2EVMMessage] executedSeqNums []uint64 + tokenPoolsMapping map[common.Address]common.Address blessedRoots map[[32]byte]bool senderNonce uint64 rateLimiterState evm_2_evm_offramp.RateLimiterTokenBucket @@ -71,14 +61,11 @@ func TestExecutionReportingPlugin_Observation(t *testing.T) { name: "happy flow", commitStorePaused: false, inflightReports: []InflightInternalExecutionReport{}, - unexpiredReports: []ccipdata.Event[commit_store.CommitStoreReportAccepted]{ + unexpiredReports: []ccipdata.Event[ccipdata.CommitStoreReport]{ { - Data: commit_store.CommitStoreReportAccepted{ - Report: commit_store.CommitStoreCommitReport{ - PriceUpdates: commit_store.InternalPriceUpdates{}, - Interval: commit_store.CommitStoreInterval{Min: 10, Max: 12}, - MerkleRoot: [32]byte{123}, - }, + Data: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: 10, Max: 12}, + MerkleRoot: [32]byte{123}, }, }, }, @@ -88,22 +75,17 @@ func TestExecutionReportingPlugin_Observation(t *testing.T) { rateLimiterState: evm_2_evm_offramp.RateLimiterTokenBucket{ IsEnabled: false, }, - senderNonce: 9, - sendRequests: []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{ + tokenPoolsMapping: map[common.Address]common.Address{}, + senderNonce: 9, + sendRequests: []ccipdata.Event[internal.EVM2EVMMessage]{ { - Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - Message: evm_2_evm_onramp.InternalEVM2EVMMessage{SequenceNumber: 10}, - }, + Data: internal.EVM2EVMMessage{SequenceNumber: 10}, }, { - Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - Message: evm_2_evm_onramp.InternalEVM2EVMMessage{SequenceNumber: 11}, - }, + Data: internal.EVM2EVMMessage{SequenceNumber: 11}, }, { - Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - Message: evm_2_evm_onramp.InternalEVM2EVMMessage{SequenceNumber: 12}, - }, + Data: internal.EVM2EVMMessage{SequenceNumber: 12}, }, }, }, @@ -117,36 +99,39 @@ func TestExecutionReportingPlugin_Observation(t *testing.T) { p.inflightReports.reports = tc.inflightReports p.lggr = logger.TestLogger(t) - commitStore, commitStoreAddr := testhelpers.NewFakeCommitStore(t, 1) - commitStore.SetPaused(tc.commitStorePaused) - commitStore.SetBlessedRoots(tc.blessedRoots) - p.config.commitStore = commitStore + commitStoreReader := ccipdata.NewMockCommitStoreReader(t) + commitStoreReader.On("IsDown", mock.Anything).Return(tc.commitStorePaused, nil) + // Blessed roots return true + for root, blessed := range tc.blessedRoots { + commitStoreReader.On("IsBlessed", mock.Anything, root).Return(blessed, nil).Maybe() + } + commitStoreReader.On("GetAcceptedCommitReportsGteTimestamp", ctx, mock.Anything, 0). + Return(tc.unexpiredReports, nil).Maybe() + p.config.commitStoreReader = commitStoreReader - offRamp, offRampAddr := testhelpers.NewFakeOffRamp(t) + offRamp, _ := testhelpers.NewFakeOffRamp(t) offRamp.SetRateLimiterState(tc.rateLimiterState) p.config.offRamp = offRamp destReader := ccipdata.NewMockReader(t) - destReader.On("GetAcceptedCommitReportsGteTimestamp", ctx, commitStoreAddr, mock.Anything, 0). - Return(tc.unexpiredReports, nil).Maybe() destReader.On("LatestBlock", ctx).Return(int64(1234), nil).Maybe() - var executionEvents []ccipdata.Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged] + p.config.destReader = destReader + + var executionEvents []ccipdata.Event[ccipdata.ExecutionStateChanged] for _, seqNum := range tc.executedSeqNums { - executionEvents = append(executionEvents, ccipdata.Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged]{ - Data: evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged{SequenceNumber: seqNum}, + executionEvents = append(executionEvents, ccipdata.Event[ccipdata.ExecutionStateChanged]{ + Data: ccipdata.ExecutionStateChanged{SequenceNumber: seqNum}, }) } - destReader.On("GetExecutionStateChangesBetweenSeqNums", ctx, offRampAddr, mock.Anything, mock.Anything, 0). + offRampReader := ccipdata.NewMockOffRampReader(t) + offRampReader.On("GetExecutionStateChangesBetweenSeqNums", ctx, mock.Anything, mock.Anything, 0). Return(executionEvents, nil).Maybe() - p.config.destReader = destReader - - onRamp, onRampAddr := testhelpers.NewFakeOnRamp(t) - p.config.onRamp = onRamp + p.config.offRampReader = offRampReader - sourceReader := ccipdata.NewMockReader(t) - sourceReader.On("GetSendRequestsBetweenSeqNums", ctx, onRampAddr, mock.Anything, mock.Anything, 0). + sourceReader := ccipdata.NewMockOnRampReader(t) + sourceReader.On("GetSendRequestsBetweenSeqNums", ctx, mock.Anything, mock.Anything, 0). Return(tc.sendRequests, nil).Maybe() - p.config.sourceReader = sourceReader + p.config.onRampReader = sourceReader cachedDestTokens := cache.NewMockAutoSync[cache.CachedTokens](t) cachedDestTokens.On("Get", ctx).Return(cache.CachedTokens{ @@ -155,12 +140,20 @@ func TestExecutionReportingPlugin_Observation(t *testing.T) { }, nil).Maybe() p.cachedDestTokens = cachedDestTokens - priceRegistry, _ := testhelpers.NewFakePriceRegistry(t) - priceRegistry.SetTokenPrices([]price_registry.InternalTimestampedPackedUint224{ - {Value: big.NewInt(123), Timestamp: uint32(time.Now().Unix())}, - }) - p.destPriceRegistry = priceRegistry - p.config.sourcePriceRegistry = priceRegistry + destPriceRegReader := ccipdata.NewMockPriceRegistryReader(t) + destPriceRegReader.On("GetTokenPrices", ctx, mock.Anything).Return( + []ccipdata.TokenPriceUpdate{{TokenPrice: ccipdata.TokenPrice{Token: common.HexToAddress("0x1"), Value: big.NewInt(123)}, Timestamp: big.NewInt(time.Now().Unix())}}, nil).Maybe() + destPriceRegReader.On("Address").Return(utils.RandomAddress()).Maybe() + sourcePriceRegReader := ccipdata.NewMockPriceRegistryReader(t) + sourcePriceRegReader.On("Address").Return(utils.RandomAddress()).Maybe() + sourcePriceRegReader.On("GetTokenPrices", ctx, mock.Anything).Return( + []ccipdata.TokenPriceUpdate{{TokenPrice: ccipdata.TokenPrice{Token: common.HexToAddress("0x1"), Value: big.NewInt(123)}, Timestamp: big.NewInt(time.Now().Unix())}}, nil).Maybe() + p.destPriceRegistry = destPriceRegReader + p.config.sourcePriceRegistry = sourcePriceRegReader + + cachedTokenPools := cache.NewMockAutoSync[map[common.Address]common.Address](t) + cachedTokenPools.On("Get", ctx).Return(tc.tokenPoolsMapping, nil).Maybe() + p.cachedTokenPools = cachedTokenPools sourceFeeTokens := cache.NewMockAutoSync[[]common.Address](t) sourceFeeTokens.On("Get", ctx).Return([]common.Address{}, nil).Maybe() @@ -186,7 +179,7 @@ func TestExecutionReportingPlugin_Report(t *testing.T) { observations []ExecutionObservation expectingSomeReport bool - expectedReport evm_2_evm_offramp.InternalExecutionReport + expectedReport ccipdata.ExecReport expectingSomeErr bool }{ { @@ -217,9 +210,9 @@ func TestExecutionReportingPlugin_Report(t *testing.T) { p.lggr = logger.TestLogger(t) p.F = tc.f - commitStore, _ := testhelpers.NewFakeCommitStore(t, tc.committedSeqNum) + //commitStore, _ := testhelpers.NewFakeCommitStore(t, tc.committedSeqNum) - p.config.commitStore = commitStore + p.config.commitStoreReader = ccipdata.NewMockCommitStoreReader(t) observations := make([]types.AttributedObservation, len(tc.observations)) for i := range observations { @@ -240,7 +233,7 @@ func TestExecutionReportingPlugin_Report(t *testing.T) { } func TestExecutionReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { - msg := evm_2_evm_offramp.InternalEVM2EVMMessage{ + msg := internal.EVM2EVMMessage{ SequenceNumber: 12, FeeTokenAmount: big.NewInt(1e9), Sender: common.Address{}, @@ -253,31 +246,35 @@ func TestExecutionReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { FeeToken: common.Address{}, MessageId: [32]byte{}, } - report := evm_2_evm_offramp.InternalExecutionReport{ - Messages: []evm_2_evm_offramp.InternalEVM2EVMMessage{msg}, + report := ccipdata.ExecReport{ + Messages: []internal.EVM2EVMMessage{msg}, OffchainTokenData: [][][]byte{{}}, Proofs: [][32]byte{{}}, ProofFlagBits: big.NewInt(1), } - encodedReport, err := abihelpers.EncodeExecutionReport(report) + encodedReport, err := ccipdata.EncodeExecutionReport(report) require.NoError(t, err) mockOffRamp, _ := testhelpers.NewFakeOffRamp(t) plugin := ExecutionReportingPlugin{ - config: ExecutionPluginConfig{ + config: ExecutionPluginStaticConfig{ offRamp: mockOffRamp, }, lggr: logger.TestLogger(t), inflightReports: newInflightExecReportsContainer(models.MustMakeDuration(1 * time.Hour).Duration()), } - mockedExecState := mockOffRamp.On("GetExecutionState", mock.Anything, uint64(12)).Return(uint8(abihelpers.ExecutionStateUntouched), nil).Once() + mockedExecState := mockOffRamp.On("GetExecutionState", mock.Anything, uint64(12)).Return(uint8(ccipdata.ExecutionStateUntouched), nil).Once() + + offRampReader := ccipdata.NewMockOffRampReader(t) + plugin.config.offRampReader = offRampReader + offRampReader.On("DecodeExecutionReport", encodedReport).Return(report, nil) should, err := plugin.ShouldAcceptFinalizedReport(testutils.Context(t), ocrtypes.ReportTimestamp{}, encodedReport) require.NoError(t, err) assert.Equal(t, true, should) - mockedExecState.Return(uint8(abihelpers.ExecutionStateSuccess), nil).Once() + mockedExecState.Return(uint8(ccipdata.ExecutionStateSuccess), nil).Once() should, err = plugin.ShouldAcceptFinalizedReport(testutils.Context(t), ocrtypes.ReportTimestamp{}, encodedReport) require.NoError(t, err) @@ -285,7 +282,7 @@ func TestExecutionReportingPlugin_ShouldAcceptFinalizedReport(t *testing.T) { } func TestExecutionReportingPlugin_ShouldTransmitAcceptedReport(t *testing.T) { - msg := evm_2_evm_offramp.InternalEVM2EVMMessage{ + msg := internal.EVM2EVMMessage{ SequenceNumber: 12, FeeTokenAmount: big.NewInt(1e9), Sender: common.Address{}, @@ -298,34 +295,38 @@ func TestExecutionReportingPlugin_ShouldTransmitAcceptedReport(t *testing.T) { FeeToken: common.Address{}, MessageId: [32]byte{}, } - report := evm_2_evm_offramp.InternalExecutionReport{ - Messages: []evm_2_evm_offramp.InternalEVM2EVMMessage{msg}, + report := ccipdata.ExecReport{ + Messages: []internal.EVM2EVMMessage{msg}, OffchainTokenData: [][][]byte{{}}, Proofs: [][32]byte{{}}, ProofFlagBits: big.NewInt(1), } - encodedReport, err := abihelpers.EncodeExecutionReport(report) + encodedReport, err := ccipdata.EncodeExecutionReport(report) require.NoError(t, err) mockOffRamp := &mock_contracts.EVM2EVMOffRampInterface{} - mockCommitStore := &mock_contracts.CommitStoreInterface{} + mockCommitStore := ccipdata.NewMockCommitStoreReader(t) plugin := ExecutionReportingPlugin{ - config: ExecutionPluginConfig{ - offRamp: mockOffRamp, - commitStore: mockCommitStore, + config: ExecutionPluginStaticConfig{ + offRamp: mockOffRamp, + commitStoreReader: mockCommitStore, }, lggr: logger.TestLogger(t), inflightReports: newInflightExecReportsContainer(models.MustMakeDuration(1 * time.Hour).Duration()), } - mockedExecState := mockOffRamp.On("GetExecutionState", mock.Anything, uint64(12)).Return(uint8(abihelpers.ExecutionStateUntouched), nil).Once() + mockedExecState := mockOffRamp.On("GetExecutionState", mock.Anything, uint64(12)).Return(uint8(ccipdata.ExecutionStateUntouched), nil).Once() + + offRampReader := ccipdata.NewMockOffRampReader(t) + plugin.config.offRampReader = offRampReader + offRampReader.On("DecodeExecutionReport", encodedReport).Return(report, nil) should, err := plugin.ShouldTransmitAcceptedReport(testutils.Context(t), ocrtypes.ReportTimestamp{}, encodedReport) require.NoError(t, err) assert.Equal(t, true, should) - mockedExecState.Return(uint8(abihelpers.ExecutionStateFailure), nil).Once() + mockedExecState.Return(uint8(ccipdata.ExecutionStateFailure), nil).Once() should, err = plugin.ShouldTransmitAcceptedReport(testutils.Context(t), ocrtypes.ReportTimestamp{}, encodedReport) require.NoError(t, err) assert.Equal(t, false, should) @@ -339,7 +340,7 @@ func TestExecutionReportingPlugin_buildReport(t *testing.T) { const bytesPerMessage = 1000 executionReport := generateExecutionReport(t, numMessages, tokensPerMessage, bytesPerMessage) - encodedReport, err := abihelpers.EncodeExecutionReport(executionReport) + encodedReport, err := ccipdata.EncodeExecutionReport(executionReport) assert.NoError(t, err) // ensure "naive" full report would be bigger than limit assert.Greater(t, len(encodedReport), MaxExecutionReportLength, "full execution report length") @@ -353,54 +354,51 @@ func TestExecutionReportingPlugin_buildReport(t *testing.T) { p := &ExecutionReportingPlugin{} p.lggr = logger.TestLogger(t) - commitStore, commitStoreAddress := testhelpers.NewFakeCommitStore(t, executionReport.Messages[len(executionReport.Messages)-1].SequenceNumber+1) - commitStore.On("Verify", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(big.NewInt(math.MaxInt64), nil) - p.config.commitStore = commitStore - - destReader := ccipdata.NewMockReader(t) - destReader.On("GetAcceptedCommitReportsGteSeqNum", ctx, commitStoreAddress, observations[0].SeqNr, 0). - Return([]ccipdata.Event[commit_store.CommitStoreReportAccepted]{ + commitStore := ccipdata.NewMockCommitStoreReader(t) + commitStore.On("VerifyExecutionReport", mock.Anything, mock.Anything, mock.Anything).Return(true, nil) + commitStore.On("GetExpectedNextSequenceNumber", mock.Anything). + Return(executionReport.Messages[len(executionReport.Messages)-1].SequenceNumber+1, nil) + commitStore.On("GetAcceptedCommitReportsGteSeqNum", ctx, observations[0].SeqNr, 0). + Return([]ccipdata.Event[ccipdata.CommitStoreReport]{ { - Data: commit_store.CommitStoreReportAccepted{ - Report: commit_store.CommitStoreCommitReport{ - Interval: commit_store.CommitStoreInterval{ - Min: observations[0].SeqNr, - Max: observations[len(observations)-1].SeqNr, - }, + Data: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{ + Min: observations[0].SeqNr, + Max: observations[len(observations)-1].SeqNr, }, }, }, }, nil) - p.config.destReader = destReader + p.config.commitStoreReader = commitStore - p.config.leafHasher = leafHasher123{} - - onRamp, onRampAddr := testhelpers.NewFakeOnRamp(t) - p.config.onRamp = onRamp + lp := lpMocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + offRampReader, err := ccipdata.NewOffRampV1_0_0(logger.TestLogger(t), utils.RandomAddress(), nil, lp, nil) + assert.NoError(t, err) + p.config.offRampReader = offRampReader - sendReqs := make([]ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], len(observations)) + sendReqs := make([]ccipdata.Event[internal.EVM2EVMMessage], len(observations)) + sourceReader := ccipdata.NewMockOnRampReader(t) for i := range observations { - sendReqs[i] = ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{ - Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{Message: evm_2_evm_onramp.InternalEVM2EVMMessage{ - SourceChainSelector: math.MaxUint64, - SequenceNumber: uint64(i + 1), - FeeTokenAmount: big.NewInt(math.MaxInt64), - Sender: utils.RandomAddress(), - Nonce: math.MaxUint64, - GasLimit: big.NewInt(math.MaxInt64), - Strict: false, - Receiver: utils.RandomAddress(), - Data: bytes.Repeat([]byte{0}, bytesPerMessage), - TokenAmounts: nil, - FeeToken: utils.RandomAddress(), - MessageId: [32]byte{12}, - }}, + msg := internal.EVM2EVMMessage{ + SourceChainSelector: math.MaxUint64, + SequenceNumber: uint64(i + 1), + FeeTokenAmount: big.NewInt(math.MaxInt64), + Sender: utils.RandomAddress(), + Nonce: math.MaxUint64, + GasLimit: big.NewInt(math.MaxInt64), + Strict: false, + Receiver: utils.RandomAddress(), + Data: bytes.Repeat([]byte{0}, bytesPerMessage), + TokenAmounts: nil, + FeeToken: utils.RandomAddress(), + MessageId: [32]byte{12}, } + sendReqs[i] = ccipdata.Event[internal.EVM2EVMMessage]{Data: msg} } - sourceReader := ccipdata.NewMockReader(t) sourceReader.On("GetSendRequestsBetweenSeqNums", - ctx, onRampAddr, observations[0].SeqNr, observations[len(observations)-1].SeqNr, 0).Return(sendReqs, nil) - p.config.sourceReader = sourceReader + ctx, observations[0].SeqNr, observations[len(observations)-1].SeqNr, 0).Return(sendReqs, nil) + p.config.onRampReader = sourceReader execReport, err := p.buildReport(ctx, p.lggr, observations) assert.NoError(t, err) @@ -408,35 +406,19 @@ func TestExecutionReportingPlugin_buildReport(t *testing.T) { } func TestExecutionReportingPlugin_buildBatch(t *testing.T) { - c, _ := testhelpers.SetupChain(t) + //_, _ := testhelpers.SetupChain(t) offRamp, _ := testhelpers.NewFakeOffRamp(t) // We do this just to have the parsing available. - onRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(common.HexToAddress("0x1"), c) - require.NoError(t, err) + //onRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(common.HexToAddress("0x1"), c) + //require.NoError(t, err) lggr := logger.TestLogger(t) sender1 := common.HexToAddress("0xa") destNative := common.HexToAddress("0xb") srcNative := common.HexToAddress("0xc") - plugin := ExecutionReportingPlugin{ - config: ExecutionPluginConfig{ - offRamp: offRamp, - onRamp: onRamp, - }, - destWrappedNative: destNative, - offchainConfig: ccipconfig.ExecOffchainConfig{ - SourceFinalityDepth: 5, - DestOptimisticConfirmations: 1, - DestFinalityDepth: 5, - BatchGasLimit: 300_000, - RelativeBoostPerWaitHour: 1, - MaxGasPrice: 1, - }, - lggr: logger.TestLogger(t), - } msg1 := internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{ + EVM2EVMMessage: internal.EVM2EVMMessage{ SequenceNumber: 1, FeeTokenAmount: big.NewInt(1e9), Sender: sender1, @@ -460,7 +442,7 @@ func TestExecutionReportingPlugin_buildBatch(t *testing.T) { msg3.Finalized = true msg4 := msg1 - msg4.TokenAmounts = []evm_2_evm_offramp.ClientEVMTokenAmount{ + msg4.TokenAmounts = []internal.TokenAmount{ {Token: srcNative, Amount: big.NewInt(100)}, } @@ -570,7 +552,7 @@ func TestExecutionReportingPlugin_buildBatch(t *testing.T) { inflight: []InflightInternalExecutionReport{ { createdAt: time.Now(), - messages: []evm_2_evm_offramp.InternalEVM2EVMMessage{msg4.InternalEVM2EVMMessage}, + messages: []internal.EVM2EVMMessage{msg4.EVM2EVMMessage}, }, }, tokenLimit: big.NewInt(19), @@ -587,7 +569,7 @@ func TestExecutionReportingPlugin_buildBatch(t *testing.T) { name: "some messages skipped after hitting max batch data len", reqs: []internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ { - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{ + EVM2EVMMessage: internal.EVM2EVMMessage{ SequenceNumber: 10, FeeTokenAmount: big.NewInt(1e9), Sender: sender1, @@ -600,7 +582,7 @@ func TestExecutionReportingPlugin_buildBatch(t *testing.T) { BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), }, { - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{ + EVM2EVMMessage: internal.EVM2EVMMessage{ SequenceNumber: 11, FeeTokenAmount: big.NewInt(1e9), Sender: sender1, @@ -613,7 +595,7 @@ func TestExecutionReportingPlugin_buildBatch(t *testing.T) { BlockTimestamp: time.Date(2010, 1, 1, 12, 12, 12, 0, time.UTC), }, { - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{ + EVM2EVMMessage: internal.EVM2EVMMessage{ SequenceNumber: 12, FeeTokenAmount: big.NewInt(1e9), Sender: sender1, @@ -640,6 +622,29 @@ func TestExecutionReportingPlugin_buildBatch(t *testing.T) { tc := tc t.Run(tc.name, func(t *testing.T) { offRamp.SetSenderNonces(tc.offRampNoncesBySender) + + gasPriceEstimator := prices.NewMockGasPriceEstimatorExec(t) + if tc.expectedSeqNrs != nil { + gasPriceEstimator.On("EstimateMsgCostUSD", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(big.NewInt(0), nil) + } + + plugin := ExecutionReportingPlugin{ + config: ExecutionPluginStaticConfig{ + offRamp: offRamp, + }, + destWrappedNative: destNative, + offchainConfig: ccipdata.ExecOffchainConfig{ + SourceFinalityDepth: 5, + DestOptimisticConfirmations: 1, + DestFinalityDepth: 5, + BatchGasLimit: 300_000, + RelativeBoostPerWaitHour: 1, + MaxGasPrice: 1, + }, + lggr: logger.TestLogger(t), + gasPriceEstimator: gasPriceEstimator, + } + seqNrs := plugin.buildBatch( context.Background(), lggr, @@ -648,7 +653,7 @@ func TestExecutionReportingPlugin_buildBatch(t *testing.T) { tc.tokenLimit, tc.srcPrices, tc.dstPrices, - func() (*big.Int, error) { return tc.destGasPrice, nil }, + func() (prices.GasPrice, error) { return tc.destGasPrice, nil }, tc.srcToDestTokens, tc.destRateLimits, ) @@ -661,7 +666,7 @@ func TestExecutionReportingPlugin_isRateLimitEnoughForTokenPool(t *testing.T) { testCases := []struct { name string destTokenPoolRateLimits map[common.Address]*big.Int - tokenAmounts []evm_2_evm_offramp.ClientEVMTokenAmount + tokenAmounts []internal.TokenAmount inflightTokenAmounts map[common.Address]*big.Int srcToDestToken map[common.Address]common.Address exp bool @@ -672,7 +677,7 @@ func TestExecutionReportingPlugin_isRateLimitEnoughForTokenPool(t *testing.T) { common.HexToAddress("10"): big.NewInt(100), common.HexToAddress("20"): big.NewInt(50), }, - tokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + tokenAmounts: []internal.TokenAmount{ {Token: common.HexToAddress("1"), Amount: big.NewInt(50)}, {Token: common.HexToAddress("2"), Amount: big.NewInt(20)}, }, @@ -696,7 +701,7 @@ func TestExecutionReportingPlugin_isRateLimitEnoughForTokenPool(t *testing.T) { common.HexToAddress("1"): common.HexToAddress("10"), common.HexToAddress("2"): common.HexToAddress("20"), }, - tokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + tokenAmounts: []internal.TokenAmount{ {Token: common.HexToAddress("1"), Amount: big.NewInt(50)}, {Token: common.HexToAddress("2"), Amount: big.NewInt(51)}, }, @@ -712,7 +717,7 @@ func TestExecutionReportingPlugin_isRateLimitEnoughForTokenPool(t *testing.T) { common.HexToAddress("1"): common.HexToAddress("10"), common.HexToAddress("2"): common.HexToAddress("20"), }, - tokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + tokenAmounts: []internal.TokenAmount{ {Token: common.HexToAddress("1"), Amount: big.NewInt(50)}, {Token: common.HexToAddress("2"), Amount: big.NewInt(20)}, }, @@ -724,7 +729,7 @@ func TestExecutionReportingPlugin_isRateLimitEnoughForTokenPool(t *testing.T) { }, { destTokenPoolRateLimits: map[common.Address]*big.Int{}, - tokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + tokenAmounts: []internal.TokenAmount{ {Token: common.HexToAddress("1"), Amount: big.NewInt(50)}, {Token: common.HexToAddress("2"), Amount: big.NewInt(20)}, }, @@ -760,17 +765,18 @@ func TestExecutionReportingPlugin_destPoolRateLimits(t *testing.T) { testCases := []struct { name string - tokenAmounts []evm_2_evm_offramp.ClientEVMTokenAmount + tokenAmounts []internal.TokenAmount sourceToDestToken map[common.Address]common.Address destPools map[common.Address]common.Address poolRateLimits map[common.Address]custom_token_pool.RateLimiterTokenBucket + destPoolsCacheErr error expRateLimits map[common.Address]*big.Int expErr bool }{ { name: "happy flow", - tokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + tokenAmounts: []internal.TokenAmount{ {Token: tk1}, {Token: tk2}, {Token: tk1}, @@ -796,7 +802,7 @@ func TestExecutionReportingPlugin_destPoolRateLimits(t *testing.T) { }, { name: "token missing from source to dest mapping", - tokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + tokenAmounts: []internal.TokenAmount{ {Token: tk1}, {Token: tk2}, // <-- missing form sourceToDestToken }, @@ -816,7 +822,7 @@ func TestExecutionReportingPlugin_destPoolRateLimits(t *testing.T) { }, { name: "pool is disabled", - tokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + tokenAmounts: []internal.TokenAmount{ {Token: tk1}, {Token: tk2}, }, @@ -837,6 +843,20 @@ func TestExecutionReportingPlugin_destPoolRateLimits(t *testing.T) { }, expErr: false, }, + { + name: "dest pool cache error", + tokenAmounts: []internal.TokenAmount{{Token: tk1}}, + sourceToDestToken: map[common.Address]common.Address{tk1: tk1dest}, + destPoolsCacheErr: errors.New("some random error"), + expErr: true, + }, + { + name: "pool for token not found", + tokenAmounts: []internal.TokenAmount{{Token: tk1}}, + sourceToDestToken: map[common.Address]common.Address{tk1: tk1dest}, + destPools: map[common.Address]common.Address{}, + expErr: true, + }, } ctx := testutils.Context(t) @@ -846,6 +866,10 @@ func TestExecutionReportingPlugin_destPoolRateLimits(t *testing.T) { p := &ExecutionReportingPlugin{} p.lggr = lggr + tokenPoolsCache := cache.NewMockAutoSync[map[common.Address]common.Address](t) + tokenPoolsCache.On("Get", ctx).Return(tc.destPools, tc.destPoolsCacheErr).Maybe() + p.cachedTokenPools = tokenPoolsCache + offRamp, offRampAddr := testhelpers.NewFakeOffRamp(t) offRamp.SetTokenPools(tc.destPools) p.config.offRamp = offRamp @@ -860,7 +884,7 @@ func TestExecutionReportingPlugin_destPoolRateLimits(t *testing.T) { { sendRequestsWithMeta: []internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ { - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{ + EVM2EVMMessage: internal.EVM2EVMMessage{ TokenAmounts: tc.tokenAmounts, }, }, @@ -877,62 +901,13 @@ func TestExecutionReportingPlugin_destPoolRateLimits(t *testing.T) { } } -func TestExecutionReportingPlugin_estimateDestinationGasPrice(t *testing.T) { - testCases := []struct { - name string - evmFee gas.EvmFee - evmFeeErr error - - expRes *big.Int - expErr bool - }{ - { - name: "dynamic fee cap has precedence over legacy", - evmFee: gas.EvmFee{ - Legacy: assets.NewWei(big.NewInt(1000)), - DynamicFeeCap: assets.NewWei(big.NewInt(2000)), - }, - expRes: big.NewInt(2000), - }, - { - name: "legacy is used if dynamic fee cap is not provided", - evmFee: gas.EvmFee{ - Legacy: assets.NewWei(big.NewInt(1000)), - }, - expRes: big.NewInt(1000), - }, - { - name: "stop on error", - evmFeeErr: errors.New("some error"), - expErr: true, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - p := &ExecutionReportingPlugin{} - mockEstimator := mocks.NewEvmFeeEstimator(t) - mockEstimator.On("GetFee", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(tc.evmFee, uint32(0), tc.evmFeeErr) - p.config.destGasEstimator = mockEstimator - - res, err := p.estimateDestinationGasPrice(testutils.Context(t)) - if tc.expErr { - assert.Error(t, err) - return - } - assert.NoError(t, err) - assert.Equal(t, tc.expRes, res) - }) - } -} - func TestExecutionReportingPlugin_getReportsWithSendRequests(t *testing.T) { testCases := []struct { name string - reports []commit_store.CommitStoreCommitReport + reports []ccipdata.CommitStoreReport expQueryMin uint64 // expected min/max used in the query to get ccipevents expQueryMax uint64 - onchainEvents []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested] + onchainEvents []ccipdata.Event[internal.EVM2EVMMessage] destLatestBlock int64 destExecutedSeqNums []uint64 @@ -947,60 +922,54 @@ func TestExecutionReportingPlugin_getReportsWithSendRequests(t *testing.T) { }, { name: "two reports happy flow", - reports: []commit_store.CommitStoreCommitReport{ + reports: []ccipdata.CommitStoreReport{ { - Interval: commit_store.CommitStoreInterval{Min: 1, Max: 2}, + Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 2}, MerkleRoot: [32]byte{100}, }, { - Interval: commit_store.CommitStoreInterval{Min: 3, Max: 3}, + Interval: ccipdata.CommitStoreInterval{Min: 3, Max: 3}, MerkleRoot: [32]byte{200}, }, }, expQueryMin: 1, expQueryMax: 3, - onchainEvents: []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{ - {Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - Message: evm_2_evm_onramp.InternalEVM2EVMMessage{SequenceNumber: 1}, - }}, - {Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - Message: evm_2_evm_onramp.InternalEVM2EVMMessage{SequenceNumber: 2}, - }}, - {Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - Message: evm_2_evm_onramp.InternalEVM2EVMMessage{SequenceNumber: 3}, - }}, + onchainEvents: []ccipdata.Event[internal.EVM2EVMMessage]{ + {Data: internal.EVM2EVMMessage{SequenceNumber: 1}}, + {Data: internal.EVM2EVMMessage{SequenceNumber: 2}}, + {Data: internal.EVM2EVMMessage{SequenceNumber: 3}}, }, destLatestBlock: 10_000, destExecutedSeqNums: []uint64{1}, expReports: []commitReportWithSendRequests{ { - commitReport: commit_store.CommitStoreCommitReport{ - Interval: commit_store.CommitStoreInterval{Min: 1, Max: 2}, + commitReport: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 2}, MerkleRoot: [32]byte{100}, }, sendRequestsWithMeta: []internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ { - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{SequenceNumber: 1}, - Executed: true, - Finalized: true, + EVM2EVMMessage: internal.EVM2EVMMessage{SequenceNumber: 1}, + Executed: true, + Finalized: true, }, { - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{SequenceNumber: 2}, - Executed: false, - Finalized: false, + EVM2EVMMessage: internal.EVM2EVMMessage{SequenceNumber: 2}, + Executed: false, + Finalized: false, }, }, }, { - commitReport: commit_store.CommitStoreCommitReport{ - Interval: commit_store.CommitStoreInterval{Min: 3, Max: 3}, + commitReport: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: 3, Max: 3}, MerkleRoot: [32]byte{200}, }, sendRequestsWithMeta: []internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ { - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{SequenceNumber: 3}, - Executed: false, - Finalized: false, + EVM2EVMMessage: internal.EVM2EVMMessage{SequenceNumber: 3}, + Executed: false, + Finalized: false, }, }, }, @@ -1016,27 +985,24 @@ func TestExecutionReportingPlugin_getReportsWithSendRequests(t *testing.T) { p := &ExecutionReportingPlugin{} p.lggr = lggr - onRamp, onRampAddr := testhelpers.NewFakeOnRamp(t) - p.config.onRamp = onRamp + offRampReader := ccipdata.NewMockOffRampReader(t) + p.config.offRampReader = offRampReader - offRamp, offRampAddr := testhelpers.NewFakeOffRamp(t) - p.config.offRamp = offRamp - - sourceReader := ccipdata.NewMockReader(t) - sourceReader.On("GetSendRequestsBetweenSeqNums", ctx, onRampAddr, tc.expQueryMin, tc.expQueryMax, 0). + sourceReader := ccipdata.NewMockOnRampReader(t) + sourceReader.On("GetSendRequestsBetweenSeqNums", ctx, tc.expQueryMin, tc.expQueryMax, 0). Return(tc.onchainEvents, nil).Maybe() - p.config.sourceReader = sourceReader + p.config.onRampReader = sourceReader destReader := ccipdata.NewMockReader(t) destReader.On("LatestBlock", ctx).Return(tc.destLatestBlock, nil).Maybe() - var executedEvents []ccipdata.Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged] + var executedEvents []ccipdata.Event[ccipdata.ExecutionStateChanged] for _, executedSeqNum := range tc.destExecutedSeqNums { - executedEvents = append(executedEvents, ccipdata.Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged]{ - Data: evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged{SequenceNumber: executedSeqNum}, - BlockMeta: ccipdata.BlockMeta{BlockNumber: tc.destLatestBlock - 10}, + executedEvents = append(executedEvents, ccipdata.Event[ccipdata.ExecutionStateChanged]{ + Data: ccipdata.ExecutionStateChanged{SequenceNumber: executedSeqNum}, + Meta: ccipdata.Meta{BlockNumber: tc.destLatestBlock - 10}, }) } - destReader.On("GetExecutionStateChangesBetweenSeqNums", ctx, offRampAddr, tc.expQueryMin, tc.expQueryMax, 0).Return(executedEvents, nil).Maybe() + offRampReader.On("GetExecutionStateChangesBetweenSeqNums", ctx, tc.expQueryMin, tc.expQueryMax, 0).Return(executedEvents, nil).Maybe() p.config.destReader = destReader populatedReports, err := p.getReportsWithSendRequests(ctx, tc.reports) @@ -1058,6 +1024,7 @@ func TestExecutionReportingPlugin_getReportsWithSendRequests(t *testing.T) { } } +/* func TestExecutionReportingPluginFactory_UpdateLogPollerFilters(t *testing.T) { const numFilters = 10 filters := make([]logpoller.Filter, numFilters) @@ -1075,7 +1042,7 @@ func TestExecutionReportingPluginFactory_UpdateLogPollerFilters(t *testing.T) { onRamp, _ := testhelpers.NewFakeOnRamp(t) sourcePriceRegistry, _ := testhelpers.NewFakePriceRegistry(t) - commitStore, _ := testhelpers.NewFakeCommitStore(t, 1) + commitStoreReader, _ := testhelpers.NewFakeCommitStore(t, 1) offRamp, _ := testhelpers.NewFakeOffRamp(t) destPriceRegistryAddr := utils.RandomAddress() @@ -1086,21 +1053,21 @@ func TestExecutionReportingPluginFactory_UpdateLogPollerFilters(t *testing.T) { filtersMu: &sync.Mutex{}, sourceChainFilters: filters[:5], destChainFilters: filters[5:10], - config: ExecutionPluginConfig{ + config: ExecutionPluginStaticConfig{ destLP: destLP, sourceLP: sourceLP, onRamp: onRamp, - commitStore: commitStore, + commitStoreReader: commitStoreReader, offRamp: offRamp, sourcePriceRegistry: sourcePriceRegistry, tokenDataProviders: tokenDataProviders, }, } - for _, f := range getExecutionPluginSourceLpChainFilters(onRamp.Address(), sourcePriceRegistry.Address(), tokenDataProviders) { + for _, f := range getExecutionPluginSourceLpChainFilters(sourcePriceRegistry.Address()) { sourceLP.On("RegisterFilter", f).Return(nil) } - for _, f := range getExecutionPluginDestLpChainFilters(commitStore.Address(), offRamp.Address(), destPriceRegistryAddr) { + for _, f := range getExecutionPluginDestLpChainFilters(commitStoreReader.Address(), offRamp.Address(), destPriceRegistryAddr) { destLP.On("RegisterFilter", f).Return(nil) } for _, f := range rf.sourceChainFilters[1:] { // zero address is skipped @@ -1113,11 +1080,13 @@ func TestExecutionReportingPluginFactory_UpdateLogPollerFilters(t *testing.T) { err := rf.UpdateLogPollerFilters(destPriceRegistryAddr) assert.NoError(t, err) } +*/ +/* func TestExecutionReportToEthTxMeta(t *testing.T) { t.Run("happy flow", func(t *testing.T) { executionReport := generateExecutionReport(t, 10, 3, 1000) - encExecReport, err := abihelpers.EncodeExecutionReport(executionReport) + encExecReport, err := ccipdata.EncodeExecutionReport(executionReport) assert.NoError(t, err) txMeta, err := ExecutionReportToEthTxMeta(encExecReport) assert.NoError(t, err) @@ -1129,7 +1098,9 @@ func TestExecutionReportToEthTxMeta(t *testing.T) { assert.Error(t, err) }) } +*/ +/* this is a test related to the cache, should not be here func TestUpdateSourceToDestTokenMapping(t *testing.T) { expectedNewBlockNumber := int64(10000) logs := []logpoller.Log{{BlockNumber: expectedNewBlockNumber}} @@ -1140,19 +1111,19 @@ func TestUpdateSourceToDestTokenMapping(t *testing.T) { sourceToken, destToken := common.HexToAddress("111111"), common.HexToAddress("222222") - mockOffRamp := &mock_contracts.EVM2EVMOffRampInterface{} + mockOffRamp := ccipdata.NewMockOffRampReader(t) mockOffRamp.On("Address").Return(common.HexToAddress("0x01")) mockOffRamp.On("GetSupportedTokens", mock.Anything).Return([]common.Address{sourceToken}, nil) mockOffRamp.On("GetDestinationToken", mock.Anything, sourceToken).Return(destToken, nil) - mockPriceRegistry := &mock_contracts.PriceRegistryInterface{} + mockPriceRegistry := ccipdata.NewMockPriceRegistryReader(t) mockPriceRegistry.On("Address").Return(common.HexToAddress("0x02")) mockPriceRegistry.On("GetFeeTokens", mock.Anything).Return([]common.Address{}, nil) plugin := ExecutionReportingPlugin{ - config: ExecutionPluginConfig{ - destLP: mockDestLP, - offRamp: mockOffRamp, + config: ExecutionPluginStaticConfig{ + destLP: mockDestLP, + offRampReader: mockOffRamp, }, cachedDestTokens: cache.NewCachedSupportedTokens(mockDestLP, mockOffRamp, mockPriceRegistry, 0), } @@ -1161,6 +1132,7 @@ func TestUpdateSourceToDestTokenMapping(t *testing.T) { require.NoError(t, err) require.Equal(t, destToken, value.SupportedTokens[sourceToken]) } +*/ func Test_calculateObservedMessagesConsensus(t *testing.T) { type args struct { @@ -1280,7 +1252,7 @@ func Test_getTokensPrices(t *testing.T) { name string feeTokens []common.Address tokens []common.Address - retPrices []price_registry.InternalTimestampedPackedUint224 + retPrices []ccipdata.TokenPriceUpdate expPrices map[common.Address]*big.Int expErr bool }{ @@ -1288,10 +1260,10 @@ func Test_getTokensPrices(t *testing.T) { name: "base", feeTokens: []common.Address{tk1, tk2}, tokens: []common.Address{tk3}, - retPrices: []price_registry.InternalTimestampedPackedUint224{ - {Value: big.NewInt(10)}, - {Value: big.NewInt(20)}, - {Value: big.NewInt(30)}, + retPrices: []ccipdata.TokenPriceUpdate{ + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(10)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(20)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(30)}}, }, expPrices: map[common.Address]*big.Int{ tk1: big.NewInt(10), @@ -1304,11 +1276,11 @@ func Test_getTokensPrices(t *testing.T) { name: "token is both fee token and normal token", feeTokens: []common.Address{tk1, tk2}, tokens: []common.Address{tk3, tk1}, - retPrices: []price_registry.InternalTimestampedPackedUint224{ - {Value: big.NewInt(10)}, - {Value: big.NewInt(20)}, - {Value: big.NewInt(30)}, - {Value: big.NewInt(10)}, + retPrices: []ccipdata.TokenPriceUpdate{ + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(10)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(20)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(30)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(10)}}, }, expPrices: map[common.Address]*big.Int{ tk1: big.NewInt(10), @@ -1321,11 +1293,11 @@ func Test_getTokensPrices(t *testing.T) { name: "token is both fee token and normal token and price registry gave different price", feeTokens: []common.Address{tk1, tk2}, tokens: []common.Address{tk3, tk1}, - retPrices: []price_registry.InternalTimestampedPackedUint224{ - {Value: big.NewInt(10)}, - {Value: big.NewInt(20)}, - {Value: big.NewInt(30)}, - {Value: big.NewInt(1000)}, // different price for same token + retPrices: []ccipdata.TokenPriceUpdate{ + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(10)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(20)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(30)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(1000)}}, }, expErr: true, }, @@ -1333,10 +1305,10 @@ func Test_getTokensPrices(t *testing.T) { name: "zero price should lead to an error", feeTokens: []common.Address{tk1, tk2}, tokens: []common.Address{tk3}, - retPrices: []price_registry.InternalTimestampedPackedUint224{ - {Value: big.NewInt(10)}, - {Value: big.NewInt(0)}, - {Value: big.NewInt(30)}, + retPrices: []ccipdata.TokenPriceUpdate{ + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(10)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(0)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(30)}}, }, expErr: true, }, @@ -1344,9 +1316,9 @@ func Test_getTokensPrices(t *testing.T) { name: "contract returns less prices than requested", feeTokens: []common.Address{tk1, tk2}, tokens: []common.Address{tk3}, - retPrices: []price_registry.InternalTimestampedPackedUint224{ - {Value: big.NewInt(10)}, - {Value: big.NewInt(20)}, + retPrices: []ccipdata.TokenPriceUpdate{ + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(10)}}, + {TokenPrice: ccipdata.TokenPrice{Value: big.NewInt(20)}}, }, expErr: true, }, @@ -1354,8 +1326,9 @@ func Test_getTokensPrices(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - priceReg, _ := testhelpers.NewFakePriceRegistry(t) - priceReg.SetTokenPrices(tc.retPrices) + priceReg := ccipdata.NewMockPriceRegistryReader(t) + priceReg.On("GetTokenPrices", mock.Anything, mock.Anything).Return(tc.retPrices, nil) + priceReg.On("Address").Return(utils.RandomAddress(), nil) prices, err := getTokensPrices(context.Background(), tc.feeTokens, priceReg, tc.tokens) if tc.expErr { @@ -1442,12 +1415,12 @@ func Test_inflightAggregates(t *testing.T) { name: "base", inflight: []InflightInternalExecutionReport{ { - messages: []evm_2_evm_offramp.InternalEVM2EVMMessage{ + messages: []internal.EVM2EVMMessage{ { Sender: addrs[0], SequenceNumber: 100, Nonce: 2, - TokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + TokenAmounts: []internal.TokenAmount{ {Token: tokenAddrs[0], Amount: big.NewInt(1e18)}, {Token: tokenAddrs[0], Amount: big.NewInt(2e18)}, }, @@ -1456,7 +1429,7 @@ func Test_inflightAggregates(t *testing.T) { Sender: addrs[0], SequenceNumber: 106, Nonce: 4, - TokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + TokenAmounts: []internal.TokenAmount{ {Token: tokenAddrs[0], Amount: big.NewInt(1e18)}, {Token: tokenAddrs[0], Amount: big.NewInt(5e18)}, {Token: tokenAddrs[2], Amount: big.NewInt(5e18)}, @@ -1491,12 +1464,12 @@ func Test_inflightAggregates(t *testing.T) { name: "missing price", inflight: []InflightInternalExecutionReport{ { - messages: []evm_2_evm_offramp.InternalEVM2EVMMessage{ + messages: []internal.EVM2EVMMessage{ { Sender: addrs[0], SequenceNumber: 100, Nonce: 2, - TokenAmounts: []evm_2_evm_offramp.ClientEVMTokenAmount{ + TokenAmounts: []internal.TokenAmount{ {Token: tokenAddrs[0], Amount: big.NewInt(1e18)}, }, }, @@ -1543,31 +1516,31 @@ func Test_inflightAggregates(t *testing.T) { func Test_commitReportWithSendRequests_validate(t *testing.T) { testCases := []struct { name string - reportInterval commit_store.CommitStoreInterval + reportInterval ccipdata.CommitStoreInterval numReqs int expValid bool }{ { name: "valid report", - reportInterval: commit_store.CommitStoreInterval{Min: 10, Max: 20}, + reportInterval: ccipdata.CommitStoreInterval{Min: 10, Max: 20}, numReqs: 11, expValid: true, }, { name: "report with one request", - reportInterval: commit_store.CommitStoreInterval{Min: 1234, Max: 1234}, + reportInterval: ccipdata.CommitStoreInterval{Min: 1234, Max: 1234}, numReqs: 1, expValid: true, }, { name: "request is missing", - reportInterval: commit_store.CommitStoreInterval{Min: 1234, Max: 1234}, + reportInterval: ccipdata.CommitStoreInterval{Min: 1234, Max: 1234}, numReqs: 0, expValid: false, }, { name: "requests are missing", - reportInterval: commit_store.CommitStoreInterval{Min: 1, Max: 10}, + reportInterval: ccipdata.CommitStoreInterval{Min: 1, Max: 10}, numReqs: 5, expValid: false, }, @@ -1576,7 +1549,7 @@ func Test_commitReportWithSendRequests_validate(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { rep := commitReportWithSendRequests{ - commitReport: commit_store.CommitStoreCommitReport{ + commitReport: ccipdata.CommitStoreReport{ Interval: tc.reportInterval, }, sendRequestsWithMeta: make([]internal.EVM2EVMOnRampCCIPSendRequestedWithMeta, tc.numReqs), @@ -1641,46 +1614,46 @@ func Test_commitReportWithSendRequests_sendReqFits(t *testing.T) { testCases := []struct { name string req internal.EVM2EVMOnRampCCIPSendRequestedWithMeta - report commit_store.CommitStoreCommitReport + report ccipdata.CommitStoreReport expRes bool }{ { name: "all requests executed and finalized", req: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{SequenceNumber: 1}, + EVM2EVMMessage: internal.EVM2EVMMessage{SequenceNumber: 1}, }, - report: commit_store.CommitStoreCommitReport{ - Interval: commit_store.CommitStoreInterval{Min: 1, Max: 10}, + report: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 10}, }, expRes: true, }, { name: "all requests executed and finalized", req: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{SequenceNumber: 10}, + EVM2EVMMessage: internal.EVM2EVMMessage{SequenceNumber: 10}, }, - report: commit_store.CommitStoreCommitReport{ - Interval: commit_store.CommitStoreInterval{Min: 1, Max: 10}, + report: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 10}, }, expRes: true, }, { name: "all requests executed and finalized", req: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{SequenceNumber: 11}, + EVM2EVMMessage: internal.EVM2EVMMessage{SequenceNumber: 11}, }, - report: commit_store.CommitStoreCommitReport{ - Interval: commit_store.CommitStoreInterval{Min: 1, Max: 10}, + report: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 10}, }, expRes: false, }, { name: "all requests executed and finalized", req: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{SequenceNumber: 10}, + EVM2EVMMessage: internal.EVM2EVMMessage{SequenceNumber: 10}, }, - report: commit_store.CommitStoreCommitReport{ - Interval: commit_store.CommitStoreInterval{Min: 10, Max: 10}, + report: ccipdata.CommitStoreReport{ + Interval: ccipdata.CommitStoreInterval{Min: 10, Max: 10}, }, expRes: true, }, @@ -1695,20 +1668,20 @@ func Test_commitReportWithSendRequests_sendReqFits(t *testing.T) { } // generateExecutionReport generates an execution report that can be used in tests -func generateExecutionReport(t *testing.T, numMsgs, tokensPerMsg, bytesPerMsg int) evm_2_evm_offramp.InternalExecutionReport { - messages := make([]evm_2_evm_offramp.InternalEVM2EVMMessage, numMsgs) +func generateExecutionReport(t *testing.T, numMsgs, tokensPerMsg, bytesPerMsg int) ccipdata.ExecReport { + messages := make([]internal.EVM2EVMMessage, numMsgs) offChainTokenData := make([][][]byte, numMsgs) for i := range messages { - tokenAmounts := make([]evm_2_evm_offramp.ClientEVMTokenAmount, tokensPerMsg) + tokenAmounts := make([]internal.TokenAmount, tokensPerMsg) for j := range tokenAmounts { - tokenAmounts[j] = evm_2_evm_offramp.ClientEVMTokenAmount{ + tokenAmounts[j] = internal.TokenAmount{ Token: utils.RandomAddress(), Amount: big.NewInt(math.MaxInt64), } } - messages[i] = evm_2_evm_offramp.InternalEVM2EVMMessage{ + messages[i] = internal.EVM2EVMMessage{ SourceChainSelector: rand.Uint64(), SequenceNumber: uint64(i + 1), FeeTokenAmount: big.NewInt(rand.Int64()), @@ -1727,7 +1700,7 @@ func generateExecutionReport(t *testing.T, numMsgs, tokensPerMsg, bytesPerMsg in offChainTokenData[i] = [][]byte{data, data, data} } - return evm_2_evm_offramp.InternalExecutionReport{ + return ccipdata.ExecReport{ Messages: messages, OffchainTokenData: offChainTokenData, Proofs: make([][32]byte, numMsgs), diff --git a/core/services/ocr2/plugins/ccip/integration_test.go b/core/services/ocr2/plugins/ccip/integration_test.go index 912b6444b4..7ef7bfb316 100644 --- a/core/services/ocr2/plugins/ccip/integration_test.go +++ b/core/services/ocr2/plugins/ccip/integration_test.go @@ -17,8 +17,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/integration" ) @@ -100,7 +99,7 @@ merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_p executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) assert.Len(t, executionLogs, 1) - ccipTH.AssertExecState(t, executionLogs[0], abihelpers.ExecutionStateSuccess) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) // Asserts // 1) The total pool input == total pool output @@ -205,7 +204,7 @@ merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_p // Should all be executed executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum+n-1) for _, execLog := range executionLogs { - ccipTH.AssertExecState(t, execLog, abihelpers.ExecutionStateSuccess) + ccipTH.AssertExecState(t, execLog, testhelpers.ExecutionStateSuccess) } currentSeqNum += n @@ -237,7 +236,7 @@ merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_p ccipTH.AllNodesHaveReqSeqNum(t, currentSeqNum, onRampV1.Address()) ccipTH.EventuallyReportCommitted(t, currentSeqNum, commitStoreV1.Address()) executionLog := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum, offRampV1.Address()) - ccipTH.AssertExecState(t, executionLog[0], abihelpers.ExecutionStateSuccess, offRampV1.Address()) + ccipTH.AssertExecState(t, executionLog[0], testhelpers.ExecutionStateSuccess, offRampV1.Address()) nonceAtOnRampV1, err := onRampV1.GetSenderNonce(nil, ccipTH.Source.User.From) require.NoError(t, err, "getting nonce from onRamp") @@ -384,7 +383,7 @@ merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_p executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, currentSeqNum, currentSeqNum) assert.Len(t, executionLogs, 1) - ccipTH.AssertExecState(t, executionLogs[0], abihelpers.ExecutionStateSuccess) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) currentSeqNum++ // get the nop fee @@ -504,15 +503,15 @@ merge [type=merge left="{}" right="{\\\"%s\\\":$(link_parse), \\\"%s\\\":$(eth_p executionLogs := ccipTH.AllNodesHaveExecutedSeqNums(t, i, i) assert.Len(t, executionLogs, 1) - ccipTH.AssertExecState(t, executionLogs[0], abihelpers.ExecutionStateSuccess) + ccipTH.AssertExecState(t, executionLogs[0], testhelpers.ExecutionStateSuccess) } for i, node := range ccipTH.Nodes { t.Logf("verifying node %d", i) - node.EventuallyNodeUsesNewCommitConfig(t, ccipTH, ccipconfig.CommitOnchainConfig{ + node.EventuallyNodeUsesNewCommitConfig(t, ccipTH, ccipdata.CommitOnchainConfig{ PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), }) - node.EventuallyNodeUsesNewExecConfig(t, ccipTH, ccipconfig.ExecOnchainConfig{ + node.EventuallyNodeUsesNewExecConfig(t, ccipTH, ccipdata.ExecOnchainConfigV1_0_0{ PermissionLessExecutionThresholdSeconds: testhelpers.PermissionLessExecutionThresholdSeconds, Router: ccipTH.Dest.Router.Address(), PriceRegistry: ccipTH.Dest.PriceRegistry.Address(), diff --git a/core/services/ocr2/plugins/ccip/internal/cache/tokenpool.go b/core/services/ocr2/plugins/ccip/internal/cache/tokenpool.go new file mode 100644 index 0000000000..a9bf1dabea --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/tokenpool.go @@ -0,0 +1,87 @@ +package cache + +import ( + "context" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + "golang.org/x/sync/errgroup" + + "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/ccip/internal/ccipdata" +) + +func NewTokenPools( + lggr logger.Logger, + lp logpoller.LogPoller, + offRamp ccipdata.OffRampReader, + optimisticConfirmations int64, + numWorkers int, +) *CachedChain[map[common.Address]common.Address] { + return &CachedChain[map[common.Address]common.Address]{ + observedEvents: offRamp.TokenEvents(), + logPoller: lp, + address: []common.Address{offRamp.Address()}, + optimisticConfirmations: optimisticConfirmations, + lock: &sync.RWMutex{}, + value: make(map[common.Address]common.Address), + lastChangeBlock: 0, + origin: newTokenPoolsOrigin(lggr, offRamp, numWorkers), + } +} + +func newTokenPoolsOrigin( + lggr logger.Logger, + offRamp ccipdata.OffRampReader, + numWorkers int) *tokenPools { + return &tokenPools{ + lggr: lggr, + offRamp: offRamp, + numWorkers: numWorkers, + } +} + +type tokenPools struct { + lggr logger.Logger + offRamp ccipdata.OffRampReader + numWorkers int +} + +func (t *tokenPools) Copy(value map[common.Address]common.Address) map[common.Address]common.Address { + return copyMap(value) +} + +func (t *tokenPools) CallOrigin(ctx context.Context) (map[common.Address]common.Address, error) { + destTokens, err := t.offRamp.GetDestinationTokens(ctx) + if err != nil { + return nil, err + } + + eg := new(errgroup.Group) + eg.SetLimit(t.numWorkers) + var mu sync.Mutex + + mapping := make(map[common.Address]common.Address, len(destTokens)) + for _, token := range destTokens { + token := token + eg.Go(func() error { + poolAddress, err := t.offRamp.GetPoolByDestToken(ctx, token) + if err != nil { + return fmt.Errorf("get token pool for token '%s': %w", token, err) + } + + mu.Lock() + mapping[token] = poolAddress + mu.Unlock() + return nil + }) + } + + if err := eg.Wait(); err != nil { + return nil, err + } + + return mapping, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/tokenpool_test.go b/core/services/ocr2/plugins/ccip/internal/cache/tokenpool_test.go new file mode 100644 index 0000000000..d6cbe42684 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/cache/tokenpool_test.go @@ -0,0 +1,146 @@ +package cache + +import ( + "math/rand" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "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/ccip/internal/ccipdata" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestNewTokenPools(t *testing.T) { + ctx := testutils.Context(t) + + tk1src := utils.RandomAddress() + tk1dst := utils.RandomAddress() + tk1pool := utils.RandomAddress() + + tk2src := utils.RandomAddress() + tk2dst := utils.RandomAddress() + tk2pool := utils.RandomAddress() + + testCases := []struct { + name string + sourceToDestTokens map[common.Address]common.Address // offramp + feeTokens []common.Address // price registry + tokenToPool map[common.Address]common.Address // offramp + expRes map[common.Address]common.Address + expErr bool + }{ + { + name: "no tokens", + sourceToDestTokens: map[common.Address]common.Address{}, + feeTokens: []common.Address{}, + tokenToPool: map[common.Address]common.Address{}, + expRes: map[common.Address]common.Address{}, + expErr: false, + }, + { + name: "happy flow", + sourceToDestTokens: map[common.Address]common.Address{ + tk1src: tk1dst, + tk2src: tk2dst, + }, + feeTokens: []common.Address{tk1dst, tk2dst}, + tokenToPool: map[common.Address]common.Address{ + tk1dst: tk1pool, + tk2dst: tk2pool, + }, + expRes: map[common.Address]common.Address{ + tk1dst: tk1pool, + tk2dst: tk2pool, + }, + expErr: false, + }, + { + name: "token pool not found", + sourceToDestTokens: map[common.Address]common.Address{ + tk1src: tk1dst, + }, + feeTokens: []common.Address{tk1dst}, + tokenToPool: map[common.Address]common.Address{}, + expErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + mockLp := mocks.NewLogPoller(t) + mockLp.On("LatestBlock", mock.Anything).Return(int64(100), nil) + + offRamp := ccipdata.NewMockOffRampReader(t) + offRamp.On("TokenEvents").Return([]common.Hash{}) + offRamp.On("Address").Return(utils.RandomAddress()) + destTokens := make([]common.Address, 0, len(tc.sourceToDestTokens)) + for _, tk := range tc.sourceToDestTokens { + destTokens = append(destTokens, tk) + } + for destToken, pool := range tc.tokenToPool { + offRamp.On("GetPoolByDestToken", mock.Anything, destToken).Return(pool, nil) + } + for _, destTk := range tc.sourceToDestTokens { + if _, exists := tc.tokenToPool[destTk]; !exists { + offRamp.On("GetPoolByDestToken", mock.Anything, destTk).Return(nil, errors.New("not found")) + } + } + offRamp.On("GetDestinationTokens", mock.Anything).Return(destTokens, nil) + + priceReg, _ := testhelpers.NewFakePriceRegistry(t) + priceReg.SetFeeTokens(tc.feeTokens) + + c := NewTokenPools(logger.TestLogger(t), mockLp, offRamp, 0, 5) + + res, err := c.Get(ctx) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, len(tc.expRes), len(res)) + for k, v := range tc.expRes { + assert.Equal(t, v, res[k]) + } + }) + } +} + +func Test_tokenPools_CallOrigin_concurrency(t *testing.T) { + numDestTokens := rand.Intn(500) + numWorkers := rand.Intn(500) + + sourceToDestTokens := make(map[common.Address]common.Address, numDestTokens) + destTokens := make([]common.Address, 0, numDestTokens) + tokenToPool := make(map[common.Address]common.Address) + for i := 0; i < numDestTokens; i++ { + sourceToken := utils.RandomAddress() + destToken := utils.RandomAddress() + destPool := utils.RandomAddress() + sourceToDestTokens[sourceToken] = destToken + tokenToPool[destToken] = destPool + destTokens = append(destTokens, destToken) + } + + offRamp := ccipdata.NewMockOffRampReader(t) + offRamp.On("GetDestinationTokens", mock.Anything).Return(destTokens, nil) + for destToken, pool := range tokenToPool { + offRamp.On("GetPoolByDestToken", mock.Anything, destToken).Return(pool, nil) + } + + origin := newTokenPoolsOrigin(logger.TestLogger(t), offRamp, numWorkers) + res, err := origin.CallOrigin(testutils.Context(t)) + assert.NoError(t, err) + + assert.Equal(t, len(tokenToPool), len(res)) + for k, v := range tokenToPool { + assert.Equal(t, v, res[k]) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/cache/tokens.go b/core/services/ocr2/plugins/ccip/internal/cache/tokens.go index 5a53cf964b..618384c0cf 100644 --- a/core/services/ocr2/plugins/ccip/internal/cache/tokens.go +++ b/core/services/ocr2/plugins/ccip/internal/cache/tokens.go @@ -11,24 +11,19 @@ import ( 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/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) // NewCachedFeeTokens cache fee tokens returned from PriceRegistry func NewCachedFeeTokens( lp logpoller.LogPoller, - priceRegistry price_registry.PriceRegistryInterface, + priceRegistry ccipdata.PriceRegistryReader, optimisticConfirmations int64, ) *CachedChain[[]common.Address] { return &CachedChain[[]common.Address]{ - observedEvents: []common.Hash{ - abihelpers.EventSignatures.FeeTokenAdded, - abihelpers.EventSignatures.FeeTokenRemoved, - }, + observedEvents: priceRegistry.FeeTokenEvents(), logPoller: lp, address: []common.Address{priceRegistry.Address()}, optimisticConfirmations: optimisticConfirmations, @@ -48,17 +43,12 @@ type CachedTokens struct { // when checking for changes in logpoller.LogPoller func NewCachedSupportedTokens( lp logpoller.LogPoller, - offRamp evm_2_evm_offramp.EVM2EVMOffRampInterface, - priceRegistry price_registry.PriceRegistryInterface, + offRamp ccipdata.OffRampReader, + priceRegistry ccipdata.PriceRegistryReader, optimisticConfirmations int64, ) *CachedChain[CachedTokens] { return &CachedChain[CachedTokens]{ - observedEvents: []common.Hash{ - abihelpers.EventSignatures.FeeTokenAdded, - abihelpers.EventSignatures.FeeTokenRemoved, - abihelpers.EventSignatures.PoolAdded, - abihelpers.EventSignatures.PoolRemoved, - }, + observedEvents: append(priceRegistry.FeeTokenEvents(), offRamp.TokenEvents()...), logPoller: lp, address: []common.Address{priceRegistry.Address(), offRamp.Address()}, optimisticConfirmations: optimisticConfirmations, @@ -74,28 +64,23 @@ func NewCachedSupportedTokens( func NewTokenToDecimals( lggr logger.Logger, lp logpoller.LogPoller, - offRamp evm_2_evm_offramp.EVM2EVMOffRampInterface, - priceRegistry price_registry.PriceRegistryInterface, + offRamp ccipdata.OffRampReader, + priceRegistryReader ccipdata.PriceRegistryReader, client evmclient.Client, optimisticConfirmations int64, ) *CachedChain[map[common.Address]uint8] { return &CachedChain[map[common.Address]uint8]{ - observedEvents: []common.Hash{ - abihelpers.EventSignatures.FeeTokenAdded, - abihelpers.EventSignatures.FeeTokenRemoved, - abihelpers.EventSignatures.PoolAdded, - abihelpers.EventSignatures.PoolRemoved, - }, + observedEvents: append(priceRegistryReader.FeeTokenEvents(), offRamp.TokenEvents()...), logPoller: lp, - address: []common.Address{priceRegistry.Address(), offRamp.Address()}, + address: []common.Address{priceRegistryReader.Address(), offRamp.Address()}, optimisticConfirmations: optimisticConfirmations, lock: &sync.RWMutex{}, value: make(map[common.Address]uint8), lastChangeBlock: 0, origin: &tokenToDecimals{ - lggr: lggr, - priceRegistry: priceRegistry, - offRamp: offRamp, + lggr: lggr, + priceRegistryReader: priceRegistryReader, + offRamp: offRamp, tokenFactory: func(token common.Address) (link_token_interface.LinkTokenInterface, error) { return link_token_interface.NewLinkToken(token, client) }, @@ -104,7 +89,7 @@ func NewTokenToDecimals( } type supportedTokensOrigin struct { - offRamp evm_2_evm_offramp.EVM2EVMOffRampInterface + offRamp ccipdata.OffRampReader } func (t *supportedTokensOrigin) Copy(value map[common.Address]common.Address) map[common.Address]common.Address { @@ -115,7 +100,7 @@ func (t *supportedTokensOrigin) Copy(value map[common.Address]common.Address) ma // NOTE: this queries the offRamp n+1 times, where n is the number of enabled tokens. func (t *supportedTokensOrigin) CallOrigin(ctx context.Context) (map[common.Address]common.Address, error) { srcToDstTokenMapping := make(map[common.Address]common.Address) - sourceTokens, err := t.offRamp.GetSupportedTokens(&bind.CallOpts{Context: ctx}) + sourceTokens, err := t.offRamp.GetSupportedTokens(ctx) if err != nil { return nil, err } @@ -123,7 +108,7 @@ func (t *supportedTokensOrigin) CallOrigin(ctx context.Context) (map[common.Addr seenDestinationTokens := make(map[common.Address]struct{}) for _, sourceToken := range sourceTokens { - dst, err1 := t.offRamp.GetDestinationToken(&bind.CallOpts{Context: ctx}, sourceToken) + dst, err1 := t.offRamp.GetDestinationToken(ctx, sourceToken) if err1 != nil { return nil, err1 } @@ -139,7 +124,7 @@ func (t *supportedTokensOrigin) CallOrigin(ctx context.Context) (map[common.Addr } type feeTokensOrigin struct { - priceRegistry price_registry.PriceRegistryInterface + priceRegistry ccipdata.PriceRegistryReader } func (t *feeTokensOrigin) Copy(value []common.Address) []common.Address { @@ -147,7 +132,7 @@ func (t *feeTokensOrigin) Copy(value []common.Address) []common.Address { } func (t *feeTokensOrigin) CallOrigin(ctx context.Context) ([]common.Address, error) { - return t.priceRegistry.GetFeeTokens(&bind.CallOpts{Context: ctx}) + return t.priceRegistry.GetFeeTokens(ctx) } func copyArray(source []common.Address) []common.Address { @@ -192,11 +177,11 @@ func copyMap[M ~map[K]V, K comparable, V any](m M) M { } type tokenToDecimals struct { - lggr logger.Logger - offRamp evm_2_evm_offramp.EVM2EVMOffRampInterface - priceRegistry price_registry.PriceRegistryInterface - tokenFactory func(address common.Address) (link_token_interface.LinkTokenInterface, error) - tokenDecimals sync.Map + lggr logger.Logger + offRamp ccipdata.OffRampReader + priceRegistryReader ccipdata.PriceRegistryReader + tokenFactory func(address common.Address) (link_token_interface.LinkTokenInterface, error) + tokenDecimals sync.Map } func (t *tokenToDecimals) Copy(value map[common.Address]uint8) map[common.Address]uint8 { @@ -206,25 +191,12 @@ func (t *tokenToDecimals) Copy(value map[common.Address]uint8) map[common.Addres // CallOrigin Generates the token to decimal mapping for dest tokens and fee tokens. // NOTE: this queries token decimals n times, where n is the number of tokens whose decimals are not already cached. func (t *tokenToDecimals) CallOrigin(ctx context.Context) (map[common.Address]uint8, error) { - mapping := make(map[common.Address]uint8) - - destTokens, err := t.offRamp.GetDestinationTokens(&bind.CallOpts{Context: ctx}) - if err != nil { - return nil, err - } - - feeTokens, err := t.priceRegistry.GetFeeTokens(&bind.CallOpts{Context: ctx}) + destTokens, err := getDestinationAndFeeTokens(ctx, t.offRamp, t.priceRegistryReader) if err != nil { return nil, err } - // In case if a fee token is not an offramp dest token, we still want to update its decimals and price - for _, feeToken := range feeTokens { - if !slices.Contains(destTokens, feeToken) { - destTokens = append(destTokens, feeToken) - } - } - + mapping := make(map[common.Address]uint8, len(destTokens)) for _, token := range destTokens { if decimals, exists := t.getCachedDecimals(token); exists { mapping[token] = decimals @@ -247,6 +219,26 @@ func (t *tokenToDecimals) CallOrigin(ctx context.Context) (map[common.Address]ui return mapping, nil } +func getDestinationAndFeeTokens(ctx context.Context, offRamp ccipdata.OffRampReader, priceRegistry ccipdata.PriceRegistryReader) ([]common.Address, error) { + destTokens, err := offRamp.GetDestinationTokens(ctx) + if err != nil { + return nil, err + } + + feeTokens, err := priceRegistry.GetFeeTokens(ctx) + if err != nil { + return nil, err + } + + for _, feeToken := range feeTokens { + if !slices.Contains(destTokens, feeToken) { + destTokens = append(destTokens, feeToken) + } + } + + return destTokens, nil +} + func (t *tokenToDecimals) getCachedDecimals(token common.Address) (uint8, bool) { rawVal, exists := t.tokenDecimals.Load(token.String()) if !exists { diff --git a/core/services/ocr2/plugins/ccip/internal/cache/tokens_test.go b/core/services/ocr2/plugins/ccip/internal/cache/tokens_test.go index 657e7d5fa1..2d79104cfa 100644 --- a/core/services/ocr2/plugins/ccip/internal/cache/tokens_test.go +++ b/core/services/ocr2/plugins/ccip/internal/cache/tokens_test.go @@ -16,7 +16,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -77,17 +77,17 @@ func Test_tokenToDecimals(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - offRamp := &mock_contracts.EVM2EVMOffRampInterface{} - offRamp.On("GetDestinationTokens", mock.Anything).Return(tt.destTokens, nil) + offRampReader := ccipdata.NewMockOffRampReader(t) + offRampReader.On("GetDestinationTokens", mock.Anything).Return(tt.destTokens, nil) - priceRegistry := &mock_contracts.PriceRegistryInterface{} - priceRegistry.On("GetFeeTokens", mock.Anything).Return(tt.feeTokens, nil) + priceRegistryReader := ccipdata.NewMockPriceRegistryReader(t) + priceRegistryReader.On("GetFeeTokens", mock.Anything).Return(tt.feeTokens, nil) tokenToDecimal := &tokenToDecimals{ - lggr: logger.TestLogger(t), - offRamp: offRamp, - priceRegistry: priceRegistry, - tokenFactory: createTokenFactory(tokenPriceMappings), + lggr: logger.TestLogger(t), + offRamp: offRampReader, + priceRegistryReader: priceRegistryReader, + tokenFactory: createTokenFactory(tokenPriceMappings), } got, err := tokenToDecimal.CallOrigin(testutils.Context(t)) @@ -142,9 +142,14 @@ func TestCallOrigin(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - offRamp, _ := testhelpers.NewFakeOffRamp(t) - offRamp.SetSourceToDestTokens(tc.srcToDst) - o := supportedTokensOrigin{offRamp: offRamp} + offRampReader := ccipdata.NewMockOffRampReader(t) + srcTks := make([]common.Address, 0, len(tc.srcToDst)) + for sourceTk, destTk := range tc.srcToDst { + offRampReader.On("GetDestinationToken", mock.Anything, sourceTk).Return(destTk, nil) + srcTks = append(srcTks, sourceTk) + } + offRampReader.On("GetSupportedTokens", mock.Anything).Return(srcTks, nil) + o := supportedTokensOrigin{offRamp: offRampReader} srcToDst, err := o.CallOrigin(context.Background()) if tc.expErr { diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go new file mode 100644 index 0000000000..a7dd40c3ab --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader.go @@ -0,0 +1,145 @@ +package ccipdata + +import ( + "time" + + "github.com/Masterminds/semver/v3" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "golang.org/x/net/context" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +type CommitStoreInterval struct { + Min, Max uint64 +} + +type CommitStoreReport struct { + TokenPrices []TokenPrice + GasPrices []GasPrice + Interval CommitStoreInterval + MerkleRoot [32]byte +} + +// Common to all versions +type CommitOnchainConfig commit_store.CommitStoreDynamicConfig + +func (d CommitOnchainConfig) AbiString() string { + return ` + [ + { + "components": [ + {"name": "priceRegistry", "type": "address"} + ], + "type": "tuple" + } + ]` +} + +func (d CommitOnchainConfig) Validate() error { + if d.PriceRegistry == (common.Address{}) { + return errors.New("must set Price Registry address") + } + return nil +} + +type CommitOffchainConfig struct { + SourceFinalityDepth uint32 + GasPriceDeviationPPB uint32 + GasPriceHeartBeat time.Duration + TokenPriceDeviationPPB uint32 + TokenPriceHeartBeat time.Duration + InflightCacheExpiry time.Duration + DestFinalityDepth uint32 +} + +//go:generate mockery --quiet --name CommitStoreReader --output . --filename commit_store_reader_mock.go --inpackage --case=underscore +type CommitStoreReader interface { + Closer + GetExpectedNextSequenceNumber(context context.Context) (uint64, error) + GetLatestPriceEpochAndRound(context context.Context) (uint64, error) + // GetAcceptedCommitReportsGteSeqNum returns all the accepted commit reports that have sequence number greater than or equal to the provided. + GetAcceptedCommitReportsGteSeqNum(ctx context.Context, seqNum uint64, confs int) ([]Event[CommitStoreReport], error) + // GetAcceptedCommitReportsGteTimestamp returns all the commit reports with timestamp greater than or equal to the provided. + GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confs int) ([]Event[CommitStoreReport], error) + IsDown(ctx context.Context) (bool, error) + IsBlessed(ctx context.Context, root [32]byte) (bool, error) + // Notifies the reader that the config has changed onchain + ChangeConfig(onchainConfig []byte, offchainConfig []byte) (common.Address, error) + OffchainConfig() CommitOffchainConfig + GasPriceEstimator() prices.GasPriceEstimatorCommit + EncodeCommitReport(report CommitStoreReport) ([]byte, error) + DecodeCommitReport(report []byte) (CommitStoreReport, error) + VerifyExecutionReport(ctx context.Context, report ExecReport) (bool, error) +} + +func NewCommitStoreReader(lggr logger.Logger, address common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator) (CommitStoreReader, error) { + contractType, version, err := ccipconfig.TypeAndVersion(address, ec) + if err != nil { + return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOnRamp, contractType) + } + switch version.String() { + case v1_0_0, v1_1_0: + return NewCommitStoreV1_0_0(lggr, address, ec, lp, estimator) + case v1_2_0: + return NewCommitStoreV1_2_0(lggr, address, ec, lp, estimator) + default: + return nil, errors.Errorf("got unexpected version %v", version.String()) + } +} + +func EncodeCommitReport(report CommitStoreReport) ([]byte, error) { + commitStoreABI := abihelpers.MustParseABI(commit_store.CommitStoreABI) + return encodeCommitReportV1_2_0(abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI), report) +} + +func CommitReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (func(report []byte) (*txmgr.TxMeta, error), error) { + if typ != ccipconfig.CommitStore { + return nil, errors.Errorf("expected %v got %v", ccipconfig.CommitStore, typ) + } + switch ver.String() { + case v1_0_0, v1_1_0: + commitStoreABI := abihelpers.MustParseABI(commit_store_1_0_0.CommitStoreABI) + return func(report []byte) (*txmgr.TxMeta, error) { + commitReport, err := decodeCommitReportV1_0_0(abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI), report) + if err != nil { + return nil, err + } + return commitReportToEthTxMeta(commitReport) + }, nil + case v1_2_0: + commitStoreABI := abihelpers.MustParseABI(commit_store.CommitStoreABI) + return func(report []byte) (*txmgr.TxMeta, error) { + commitReport, err := decodeCommitReportV1_2_0(abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI), report) + if err != nil { + return nil, err + } + return commitReportToEthTxMeta(commitReport) + }, nil + default: + return nil, errors.Errorf("got unexpected version %v", ver.String()) + } +} + +// CommitReportToEthTxMeta generates a txmgr.EthTxMeta from the given commit report. +// sequence numbers of the committed messages will be added to tx metadata +func commitReportToEthTxMeta(commitReport CommitStoreReport) (*txmgr.TxMeta, error) { + n := uint64(commitReport.Interval.Max-commitReport.Interval.Min) + 1 + seqRange := make([]uint64, n) + for i := uint64(0); i < n; i++ { + seqRange[i] = i + commitReport.Interval.Min + } + return &txmgr.TxMeta{ + SeqNumbers: seqRange, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_mock.go new file mode 100644 index 0000000000..89b2fedf2d --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_mock.go @@ -0,0 +1,335 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package ccipdata + +import ( + context "context" + + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" + + prices "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + + time "time" +) + +// MockCommitStoreReader is an autogenerated mock type for the CommitStoreReader type +type MockCommitStoreReader struct { + mock.Mock +} + +// ChangeConfig provides a mock function with given fields: onchainConfig, offchainConfig +func (_m *MockCommitStoreReader) ChangeConfig(onchainConfig []byte, offchainConfig []byte) (common.Address, error) { + ret := _m.Called(onchainConfig, offchainConfig) + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func([]byte, []byte) (common.Address, error)); ok { + return rf(onchainConfig, offchainConfig) + } + if rf, ok := ret.Get(0).(func([]byte, []byte) common.Address); ok { + r0 = rf(onchainConfig, offchainConfig) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func([]byte, []byte) error); ok { + r1 = rf(onchainConfig, offchainConfig) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Close provides a mock function with given fields: qopts +func (_m *MockCommitStoreReader) Close(qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 error + if rf, ok := ret.Get(0).(func(...pg.QOpt) error); ok { + r0 = rf(qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DecodeCommitReport provides a mock function with given fields: report +func (_m *MockCommitStoreReader) DecodeCommitReport(report []byte) (CommitStoreReport, error) { + ret := _m.Called(report) + + var r0 CommitStoreReport + var r1 error + if rf, ok := ret.Get(0).(func([]byte) (CommitStoreReport, error)); ok { + return rf(report) + } + if rf, ok := ret.Get(0).(func([]byte) CommitStoreReport); ok { + r0 = rf(report) + } else { + r0 = ret.Get(0).(CommitStoreReport) + } + + if rf, ok := ret.Get(1).(func([]byte) error); ok { + r1 = rf(report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EncodeCommitReport provides a mock function with given fields: report +func (_m *MockCommitStoreReader) EncodeCommitReport(report CommitStoreReport) ([]byte, error) { + ret := _m.Called(report) + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(CommitStoreReport) ([]byte, error)); ok { + return rf(report) + } + if rf, ok := ret.Get(0).(func(CommitStoreReport) []byte); ok { + r0 = rf(report) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(CommitStoreReport) error); ok { + r1 = rf(report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GasPriceEstimator provides a mock function with given fields: +func (_m *MockCommitStoreReader) GasPriceEstimator() prices.GasPriceEstimatorCommit { + ret := _m.Called() + + var r0 prices.GasPriceEstimatorCommit + if rf, ok := ret.Get(0).(func() prices.GasPriceEstimatorCommit); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(prices.GasPriceEstimatorCommit) + } + } + + return r0 +} + +// GetAcceptedCommitReportsGteSeqNum provides a mock function with given fields: ctx, seqNum, confs +func (_m *MockCommitStoreReader) GetAcceptedCommitReportsGteSeqNum(ctx context.Context, seqNum uint64, confs int) ([]Event[CommitStoreReport], error) { + ret := _m.Called(ctx, seqNum, confs) + + var r0 []Event[CommitStoreReport] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, int) ([]Event[CommitStoreReport], error)); ok { + return rf(ctx, seqNum, confs) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, int) []Event[CommitStoreReport]); ok { + r0 = rf(ctx, seqNum, confs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]Event[CommitStoreReport]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, int) error); ok { + r1 = rf(ctx, seqNum, confs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAcceptedCommitReportsGteTimestamp provides a mock function with given fields: ctx, ts, confs +func (_m *MockCommitStoreReader) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confs int) ([]Event[CommitStoreReport], error) { + ret := _m.Called(ctx, ts, confs) + + var r0 []Event[CommitStoreReport] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) ([]Event[CommitStoreReport], error)); ok { + return rf(ctx, ts, confs) + } + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) []Event[CommitStoreReport]); ok { + r0 = rf(ctx, ts, confs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]Event[CommitStoreReport]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, time.Time, int) error); ok { + r1 = rf(ctx, ts, confs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetExpectedNextSequenceNumber provides a mock function with given fields: _a0 +func (_m *MockCommitStoreReader) GetExpectedNextSequenceNumber(_a0 context.Context) (uint64, error) { + ret := _m.Called(_a0) + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (uint64, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) uint64); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetLatestPriceEpochAndRound provides a mock function with given fields: _a0 +func (_m *MockCommitStoreReader) GetLatestPriceEpochAndRound(_a0 context.Context) (uint64, error) { + ret := _m.Called(_a0) + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (uint64, error)); ok { + return rf(_a0) + } + if rf, ok := ret.Get(0).(func(context.Context) uint64); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// IsBlessed provides a mock function with given fields: ctx, root +func (_m *MockCommitStoreReader) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + ret := _m.Called(ctx, root) + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, [32]byte) (bool, error)); ok { + return rf(ctx, root) + } + if rf, ok := ret.Get(0).(func(context.Context, [32]byte) bool); ok { + r0 = rf(ctx, root) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, [32]byte) error); ok { + r1 = rf(ctx, root) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// IsDown provides a mock function with given fields: ctx +func (_m *MockCommitStoreReader) IsDown(ctx context.Context) (bool, error) { + ret := _m.Called(ctx) + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (bool, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) bool); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffchainConfig provides a mock function with given fields: +func (_m *MockCommitStoreReader) OffchainConfig() CommitOffchainConfig { + ret := _m.Called() + + var r0 CommitOffchainConfig + if rf, ok := ret.Get(0).(func() CommitOffchainConfig); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(CommitOffchainConfig) + } + + return r0 +} + +// VerifyExecutionReport provides a mock function with given fields: ctx, report +func (_m *MockCommitStoreReader) VerifyExecutionReport(ctx context.Context, report ExecReport) (bool, error) { + ret := _m.Called(ctx, report) + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, ExecReport) (bool, error)); ok { + return rf(ctx, report) + } + if rf, ok := ret.Get(0).(func(context.Context, ExecReport) bool); ok { + r0 = rf(ctx, report) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, ExecReport) error); ok { + r1 = rf(ctx, report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +type mockConstructorTestingTNewMockCommitStoreReader interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockCommitStoreReader creates a new instance of MockCommitStoreReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockCommitStoreReader(t mockConstructorTestingTNewMockCommitStoreReader) *MockCommitStoreReader { + mock := &MockCommitStoreReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go new file mode 100644 index 0000000000..9bdbad4076 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_reader_test.go @@ -0,0 +1,161 @@ +package ccipdata + +import ( + "math/big" + "math/rand" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "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/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/store/models" +) + +func assertFilterRegistration(t *testing.T, lp *lpmocks.LogPoller, buildCloser func(lp *lpmocks.LogPoller, addr common.Address) Closer, numFilter int) { + // Expected filter properties for a closer: + // - Should be the same filter set registered that is unregistered + // - Should be registered to the address specified + // - Number of events specific to this component should be registered + addr := common.HexToAddress("0x1234") + var filters []logpoller.Filter + + lp.On("RegisterFilter", mock.Anything).Run(func(args mock.Arguments) { + f := args.Get(0).(logpoller.Filter) + require.Equal(t, len(f.Addresses), 1) + require.Equal(t, f.Addresses[0], addr) + filters = append(filters, f) + }).Return(nil).Times(numFilter) + + c := buildCloser(lp, addr) + for _, filter := range filters { + lp.On("UnregisterFilter", filter.Name).Return(nil) + } + + require.NoError(t, c.Close()) + lp.AssertExpectations(t) +} + +func TestCommitFilters(t *testing.T) { + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { + c, err := NewCommitStoreV1_0_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) + require.NoError(t, err) + return c + }, 1) + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { + c, err := NewCommitStoreV1_2_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) + require.NoError(t, err) + return c + }, 1) +} + +func TestCommitOffchainConfig_Encoding(t *testing.T) { + tests := map[string]struct { + want CommitOffchainConfigV1_2_0 + expectErr bool + }{ + "encodes and decodes config with all fields set": { + want: CommitOffchainConfigV1_2_0{ + SourceFinalityDepth: 3, + DestFinalityDepth: 3, + GasPriceHeartBeat: models.MustMakeDuration(1 * time.Hour), + DAGasPriceDeviationPPB: 5e7, + ExecGasPriceDeviationPPB: 5e7, + TokenPriceHeartBeat: models.MustMakeDuration(1 * time.Hour), + TokenPriceDeviationPPB: 5e7, + MaxGasPrice: 200e9, + InflightCacheExpiry: models.MustMakeDuration(23456 * time.Second), + }, + }, + "fails decoding when all fields present but with 0 values": { + want: CommitOffchainConfigV1_2_0{ + SourceFinalityDepth: 0, + DestFinalityDepth: 0, + GasPriceHeartBeat: models.MustMakeDuration(0), + DAGasPriceDeviationPPB: 0, + ExecGasPriceDeviationPPB: 0, + TokenPriceHeartBeat: models.MustMakeDuration(0), + TokenPriceDeviationPPB: 0, + MaxGasPrice: 0, + InflightCacheExpiry: models.MustMakeDuration(0), + }, + expectErr: true, + }, + "fails decoding when all fields are missing": { + want: CommitOffchainConfigV1_2_0{}, + expectErr: true, + }, + "fails decoding when some fields are missing": { + want: CommitOffchainConfigV1_2_0{ + SourceFinalityDepth: 3, + GasPriceHeartBeat: models.MustMakeDuration(1 * time.Hour), + DAGasPriceDeviationPPB: 5e7, + ExecGasPriceDeviationPPB: 5e7, + TokenPriceHeartBeat: models.MustMakeDuration(1 * time.Hour), + TokenPriceDeviationPPB: 5e7, + MaxGasPrice: 200e9, + }, + expectErr: true, + }, + } + for name, tc := range tests { + t.Run(name, func(t *testing.T) { + encode, err := ccipconfig.EncodeOffchainConfig(tc.want) + require.NoError(t, err) + got, err := ccipconfig.DecodeOffchainConfig[CommitOffchainConfigV1_2_0](encode) + + if tc.expectErr { + require.ErrorContains(t, err, "must set") + } else { + require.NoError(t, err) + require.Equal(t, tc.want, got) + } + }) + } +} + +func randomAddress() common.Address { + return common.BigToAddress(big.NewInt(rand.Int63())) +} + +func TestCommitOnchainConfig(t *testing.T) { + tests := []struct { + name string + want CommitOnchainConfig + expectErr bool + }{ + { + name: "encodes and decodes config with all fields set", + want: CommitOnchainConfig{ + PriceRegistry: randomAddress(), + }, + expectErr: false, + }, + { + name: "encodes and fails decoding config with missing fields", + want: CommitOnchainConfig{}, + expectErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + encoded, err := abihelpers.EncodeAbiStruct(tt.want) + require.NoError(t, err) + + decoded, err := abihelpers.DecodeAbiStruct[CommitOnchainConfig](encoded) + if tt.expectErr { + require.ErrorContains(t, err, "must set") + } else { + require.NoError(t, err) + require.Equal(t, tt.want, decoded) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go new file mode 100644 index 0000000000..ee9eb729b0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0.go @@ -0,0 +1,352 @@ +package ccipdata + +import ( + "math/big" + "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/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + "golang.org/x/net/context" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/store/models" +) + +const ( + EXEC_REPORT_ACCEPTS = "Exec report accepts" + ReportAccepted = "ReportAccepted" +) + +var _ CommitStoreReader = &CommitStoreV1_0_0{} + +type CommitStoreV1_0_0 struct { + // Static config + commitStore *commit_store_1_0_0.CommitStore + lggr logger.Logger + lp logpoller.LogPoller + address common.Address + estimator gas.EvmFeeEstimator + filters []logpoller.Filter + reportAcceptedSig common.Hash + reportAcceptedMaxSeqIndex int + commitReportArgs abi.Arguments + + // Dynamic config + configMu sync.RWMutex + gasPriceEstimator prices.ExecGasPriceEstimator + offchainConfig CommitOffchainConfig +} + +func (c *CommitStoreV1_0_0) EncodeCommitReport(report CommitStoreReport) ([]byte, error) { + return encodeCommitReportV1_0_0(c.commitReportArgs, report) +} + +func encodeCommitReportV1_0_0(commitReportArgs abi.Arguments, report CommitStoreReport) ([]byte, error) { + var tokenPriceUpdates []commit_store_1_0_0.InternalTokenPriceUpdate + for _, tokenPriceUpdate := range report.TokenPrices { + tokenPriceUpdates = append(tokenPriceUpdates, commit_store_1_0_0.InternalTokenPriceUpdate{ + SourceToken: tokenPriceUpdate.Token, + UsdPerToken: tokenPriceUpdate.Value, + }) + } + var usdPerUnitGas = big.NewInt(0) + var destChainSelector = uint64(0) + if len(report.GasPrices) > 0 { + usdPerUnitGas = report.GasPrices[0].Value + destChainSelector = report.GasPrices[0].DestChainSelector + } + rep := commit_store_1_0_0.CommitStoreCommitReport{ + PriceUpdates: commit_store_1_0_0.InternalPriceUpdates{ + TokenPriceUpdates: tokenPriceUpdates, + UsdPerUnitGas: usdPerUnitGas, + DestChainSelector: destChainSelector, + }, + Interval: commit_store_1_0_0.CommitStoreInterval{Min: report.Interval.Min, Max: report.Interval.Max}, + MerkleRoot: report.MerkleRoot, + } + return commitReportArgs.PackValues([]interface{}{rep}) +} + +func decodeCommitReportV1_0_0(commitReportArgs abi.Arguments, report []byte) (CommitStoreReport, error) { + unpacked, err := commitReportArgs.Unpack(report) + if err != nil { + return CommitStoreReport{}, err + } + if len(unpacked) != 1 { + return CommitStoreReport{}, errors.New("expected single struct value") + } + + commitReport, ok := unpacked[0].(struct { + PriceUpdates struct { + TokenPriceUpdates []struct { + SourceToken common.Address `json:"sourceToken"` + UsdPerToken *big.Int `json:"usdPerToken"` + } `json:"tokenPriceUpdates"` + DestChainSelector uint64 `json:"destChainSelector"` + UsdPerUnitGas *big.Int `json:"usdPerUnitGas"` + } `json:"priceUpdates"` + Interval struct { + Min uint64 `json:"min"` + Max uint64 `json:"max"` + } `json:"interval"` + MerkleRoot [32]byte `json:"merkleRoot"` + }) + if !ok { + return CommitStoreReport{}, errors.Errorf("invalid commit report got %T", unpacked[0]) + } + + var tokenPriceUpdates []TokenPrice + for _, u := range commitReport.PriceUpdates.TokenPriceUpdates { + tokenPriceUpdates = append(tokenPriceUpdates, TokenPrice{ + Token: u.SourceToken, + Value: u.UsdPerToken, + }) + } + + var gasPrices []GasPrice + if commitReport.PriceUpdates.DestChainSelector != 0 { + // No gas price update { + gasPrices = append(gasPrices, GasPrice{ + DestChainSelector: commitReport.PriceUpdates.DestChainSelector, + Value: commitReport.PriceUpdates.UsdPerUnitGas, + }) + } + + return CommitStoreReport{ + TokenPrices: tokenPriceUpdates, + GasPrices: gasPrices, + Interval: CommitStoreInterval{ + Min: commitReport.Interval.Min, + Max: commitReport.Interval.Max, + }, + MerkleRoot: commitReport.MerkleRoot, + }, nil +} + +func (c *CommitStoreV1_0_0) DecodeCommitReport(report []byte) (CommitStoreReport, error) { + return decodeCommitReportV1_0_0(c.commitReportArgs, report) +} + +func (c *CommitStoreV1_0_0) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + return c.commitStore.IsBlessed(&bind.CallOpts{Context: ctx}, root) +} + +func (c *CommitStoreV1_0_0) OffchainConfig() CommitOffchainConfig { + c.configMu.RLock() + defer c.configMu.RUnlock() + return c.offchainConfig +} + +func (c *CommitStoreV1_0_0) GasPriceEstimator() prices.GasPriceEstimatorCommit { + c.configMu.RLock() + defer c.configMu.RUnlock() + return c.gasPriceEstimator +} + +// CommitOffchainConfigV1_0_0 is a legacy version of CommitOffchainConfigV1_2_0, used for CommitStore version 1.0.0 and 1.1.0 +type CommitOffchainConfigV1_0_0 struct { + SourceFinalityDepth uint32 + DestFinalityDepth uint32 + FeeUpdateHeartBeat models.Duration + FeeUpdateDeviationPPB uint32 + MaxGasPrice uint64 + InflightCacheExpiry models.Duration +} + +func (c CommitOffchainConfigV1_0_0) Validate() error { + if c.SourceFinalityDepth == 0 { + return errors.New("must set SourceFinalityDepth") + } + if c.DestFinalityDepth == 0 { + return errors.New("must set DestFinalityDepth") + } + if c.FeeUpdateHeartBeat.Duration() == 0 { + return errors.New("must set FeeUpdateHeartBeat") + } + if c.FeeUpdateDeviationPPB == 0 { + return errors.New("must set FeeUpdateDeviationPPB") + } + if c.MaxGasPrice == 0 { + return errors.New("must set MaxGasPrice") + } + if c.InflightCacheExpiry.Duration() == 0 { + return errors.New("must set InflightCacheExpiry") + } + + return nil +} + +func (c *CommitStoreV1_0_0) ChangeConfig(onchainConfig []byte, offchainConfig []byte) (common.Address, error) { + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[CommitOnchainConfig](onchainConfig) + if err != nil { + return common.Address{}, err + } + + offchainConfigV1, err := ccipconfig.DecodeOffchainConfig[CommitOffchainConfigV1_0_0](offchainConfig) + if err != nil { + return common.Address{}, err + } + c.configMu.Lock() + c.gasPriceEstimator = prices.NewExecGasPriceEstimator( + c.estimator, + big.NewInt(int64(offchainConfigV1.MaxGasPrice)), + int64(offchainConfigV1.FeeUpdateDeviationPPB)) + c.offchainConfig = CommitOffchainConfig{ + SourceFinalityDepth: offchainConfigV1.SourceFinalityDepth, + GasPriceDeviationPPB: offchainConfigV1.FeeUpdateDeviationPPB, + TokenPriceDeviationPPB: offchainConfigV1.FeeUpdateDeviationPPB, + InflightCacheExpiry: offchainConfigV1.InflightCacheExpiry.Duration(), + DestFinalityDepth: offchainConfigV1.DestFinalityDepth, + } + c.configMu.Unlock() + c.lggr.Infow("ChangeConfig", + "offchainConfig", offchainConfigV1, + "onchainConfig", onchainConfigParsed, + ) + return onchainConfigParsed.PriceRegistry, nil +} + +func (c *CommitStoreV1_0_0) Close(qopts ...pg.QOpt) error { + return logpollerutil.UnregisterLpFilters(c.lp, c.filters, qopts...) +} + +func (c *CommitStoreV1_0_0) parseReport(log types.Log) (*CommitStoreReport, error) { + repAccepted, err := c.commitStore.ParseReportAccepted(log) + if err != nil { + return nil, err + } + // Translate to common struct. + var tokenPrices []TokenPrice + for _, tpu := range repAccepted.Report.PriceUpdates.TokenPriceUpdates { + tokenPrices = append(tokenPrices, TokenPrice{ + Token: tpu.SourceToken, + Value: tpu.UsdPerToken, + }) + } + return &CommitStoreReport{ + TokenPrices: tokenPrices, + GasPrices: []GasPrice{{DestChainSelector: repAccepted.Report.PriceUpdates.DestChainSelector, Value: repAccepted.Report.PriceUpdates.UsdPerUnitGas}}, + MerkleRoot: repAccepted.Report.MerkleRoot, + Interval: CommitStoreInterval{Min: repAccepted.Report.Interval.Min, Max: repAccepted.Report.Interval.Max}, + }, nil +} + +func (c *CommitStoreV1_0_0) GetAcceptedCommitReportsGteSeqNum(ctx context.Context, seqNum uint64, confs int) ([]Event[CommitStoreReport], error) { + logs, err := c.lp.LogsDataWordGreaterThan( + c.reportAcceptedSig, + c.address, + c.reportAcceptedMaxSeqIndex, + logpoller.EvmWord(seqNum), + confs, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, err + } + + return parseLogs[CommitStoreReport]( + logs, + c.lggr, + c.parseReport, + ) +} + +func (c *CommitStoreV1_0_0) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confs int) ([]Event[CommitStoreReport], error) { + logs, err := c.lp.LogsCreatedAfter( + c.reportAcceptedSig, + c.address, + ts, + confs, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, err + } + + return parseLogs[CommitStoreReport]( + logs, + c.lggr, + c.parseReport, + ) +} + +func (c *CommitStoreV1_0_0) GetExpectedNextSequenceNumber(ctx context.Context) (uint64, error) { + return c.commitStore.GetExpectedNextSequenceNumber(&bind.CallOpts{Context: ctx}) +} + +func (c *CommitStoreV1_0_0) GetLatestPriceEpochAndRound(ctx context.Context) (uint64, error) { + return c.commitStore.GetLatestPriceEpochAndRound(&bind.CallOpts{Context: ctx}) +} + +func (c *CommitStoreV1_0_0) IsDown(ctx context.Context) (bool, error) { + unPausedAndHealthy, err := c.commitStore.IsUnpausedAndARMHealthy(&bind.CallOpts{Context: ctx}) + if err != nil { + // If we cannot read the state, assume the worst + c.lggr.Errorw("Unable to read CommitStore IsUnpausedAndARMHealthy", "err", err) + return true, nil + } + return !unPausedAndHealthy, nil +} + +func (c *CommitStoreV1_0_0) VerifyExecutionReport(ctx context.Context, report ExecReport) (bool, error) { + var hashes [][32]byte + for _, msg := range report.Messages { + hashes = append(hashes, msg.Hash) + } + res, err := c.commitStore.Verify(&bind.CallOpts{Context: ctx}, hashes, report.Proofs, report.ProofFlagBits) + if err != nil { + c.lggr.Errorw("Unable to call verify", "messages", report.Messages, "err", err) + return false, nil + } + // No timestamp, means failed to verify root. + if res.Cmp(big.NewInt(0)) == 0 { + c.lggr.Errorw("Root does not verify", "messages", report.Messages) + return false, nil + } + return true, nil +} + +func NewCommitStoreV1_0_0(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator) (*CommitStoreV1_0_0, error) { + commitStore, err := commit_store_1_0_0.NewCommitStore(addr, ec) + if err != nil { + return nil, err + } + commitStoreABI := abihelpers.MustParseABI(commit_store_1_0_0.CommitStoreABI) + eventSig := abihelpers.MustGetEventID(ReportAccepted, commitStoreABI) + commitReportArgs := abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI) + var filters = []logpoller.Filter{ + { + Name: logpoller.FilterName(EXEC_REPORT_ACCEPTS, addr.String()), + EventSigs: []common.Hash{eventSig}, + Addresses: []common.Address{addr}, + }, + } + if err := logpollerutil.RegisterLpFilters(lp, filters); err != nil { + return nil, err + } + return &CommitStoreV1_0_0{ + commitStore: commitStore, + address: addr, + lggr: lggr, + lp: lp, + estimator: estimator, + filters: filters, + commitReportArgs: commitReportArgs, + reportAcceptedSig: eventSig, + // offset || priceUpdatesOffset || minSeqNum || maxSeqNum || merkleRoot + reportAcceptedMaxSeqIndex: 3, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go new file mode 100644 index 0000000000..52c88df608 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_0_0_test.go @@ -0,0 +1,49 @@ +package ccipdata + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "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/utils" +) + +func TestCommitReportEncodingV1_0_0(t *testing.T) { + report := CommitStoreReport{ + TokenPrices: []TokenPrice{ + { + Token: utils.RandomAddress(), + Value: big.NewInt(9e18), + }, + }, + GasPrices: []GasPrice{ + { + DestChainSelector: rand.Uint64(), + Value: big.NewInt(2000e9), + }, + }, + MerkleRoot: [32]byte{123}, + Interval: CommitStoreInterval{Min: 1, Max: 10}, + } + + lp := mocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + + c, err := NewCommitStoreV1_0_0(logger.TestLogger(t), randomAddress(), nil, lp, nil) + assert.NoError(t, err) + + encodedReport, err := c.EncodeCommitReport(report) + require.NoError(t, err) + assert.Greater(t, len(encodedReport), 0) + + decodedReport, err := c.DecodeCommitReport(encodedReport) + require.NoError(t, err) + require.Equal(t, report.TokenPrices, decodedReport.TokenPrices) + require.Equal(t, report, decodedReport) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go new file mode 100644 index 0000000000..915b18b302 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0.go @@ -0,0 +1,374 @@ +package ccipdata + +import ( + "context" + "math/big" + "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/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/store/models" +) + +var _ CommitStoreReader = &CommitStoreV1_2_0{} + +type CommitStoreV1_2_0 struct { + // Static config + commitStore *commit_store.CommitStore + lggr logger.Logger + lp logpoller.LogPoller + address common.Address + estimator gas.EvmFeeEstimator + filters []logpoller.Filter + reportAcceptedSig common.Hash + reportAcceptedMaxSeqIndex int + commitReportArgs abi.Arguments + + // Dynamic config + configMu sync.RWMutex + gasPriceEstimator prices.DAGasPriceEstimator + offchainConfig CommitOffchainConfig +} + +func (c *CommitStoreV1_2_0) EncodeCommitReport(report CommitStoreReport) ([]byte, error) { + return encodeCommitReportV1_2_0(c.commitReportArgs, report) +} + +func encodeCommitReportV1_2_0(commitReportArgs abi.Arguments, report CommitStoreReport) ([]byte, error) { + var tokenPriceUpdates []commit_store.InternalTokenPriceUpdate + for _, tokenPriceUpdate := range report.TokenPrices { + tokenPriceUpdates = append(tokenPriceUpdates, commit_store.InternalTokenPriceUpdate{ + SourceToken: tokenPriceUpdate.Token, + UsdPerToken: tokenPriceUpdate.Value, + }) + } + + var gasPriceUpdates []commit_store.InternalGasPriceUpdate + for _, gasPriceUpdate := range report.GasPrices { + gasPriceUpdates = append(gasPriceUpdates, commit_store.InternalGasPriceUpdate{ + DestChainSelector: gasPriceUpdate.DestChainSelector, + UsdPerUnitGas: gasPriceUpdate.Value, + }) + } + + rep := commit_store.CommitStoreCommitReport{ + PriceUpdates: commit_store.InternalPriceUpdates{ + TokenPriceUpdates: tokenPriceUpdates, + GasPriceUpdates: gasPriceUpdates, + }, + Interval: commit_store.CommitStoreInterval{Min: report.Interval.Min, Max: report.Interval.Max}, + MerkleRoot: report.MerkleRoot, + } + return commitReportArgs.PackValues([]interface{}{rep}) +} + +func decodeCommitReportV1_2_0(commitReportArgs abi.Arguments, report []byte) (CommitStoreReport, error) { + unpacked, err := commitReportArgs.Unpack(report) + if err != nil { + return CommitStoreReport{}, err + } + if len(unpacked) != 1 { + return CommitStoreReport{}, errors.New("expected single struct value") + } + + commitReport, ok := unpacked[0].(struct { + PriceUpdates struct { + TokenPriceUpdates []struct { + SourceToken common.Address `json:"sourceToken"` + UsdPerToken *big.Int `json:"usdPerToken"` + } `json:"tokenPriceUpdates"` + GasPriceUpdates []struct { + DestChainSelector uint64 `json:"destChainSelector"` + UsdPerUnitGas *big.Int `json:"usdPerUnitGas"` + } `json:"gasPriceUpdates"` + } `json:"priceUpdates"` + Interval struct { + Min uint64 `json:"min"` + Max uint64 `json:"max"` + } `json:"interval"` + MerkleRoot [32]byte `json:"merkleRoot"` + }) + if !ok { + return CommitStoreReport{}, errors.Errorf("invalid commit report got %T", unpacked[0]) + } + + var tokenPriceUpdates []TokenPrice + for _, u := range commitReport.PriceUpdates.TokenPriceUpdates { + tokenPriceUpdates = append(tokenPriceUpdates, TokenPrice{ + Token: u.SourceToken, + Value: u.UsdPerToken, + }) + } + + var gasPrices []GasPrice + for _, u := range commitReport.PriceUpdates.GasPriceUpdates { + gasPrices = append(gasPrices, GasPrice{ + DestChainSelector: u.DestChainSelector, + Value: u.UsdPerUnitGas, + }) + } + + return CommitStoreReport{ + TokenPrices: tokenPriceUpdates, + GasPrices: gasPrices, + Interval: CommitStoreInterval{ + Min: commitReport.Interval.Min, + Max: commitReport.Interval.Max, + }, + MerkleRoot: commitReport.MerkleRoot, + }, nil +} + +func (c *CommitStoreV1_2_0) DecodeCommitReport(report []byte) (CommitStoreReport, error) { + return decodeCommitReportV1_2_0(c.commitReportArgs, report) +} + +func (c *CommitStoreV1_2_0) IsBlessed(ctx context.Context, root [32]byte) (bool, error) { + return c.commitStore.IsBlessed(&bind.CallOpts{Context: ctx}, root) +} + +func (c *CommitStoreV1_2_0) OffchainConfig() CommitOffchainConfig { + c.configMu.RLock() + defer c.configMu.RUnlock() + return c.offchainConfig +} + +func (c *CommitStoreV1_2_0) GasPriceEstimator() prices.GasPriceEstimatorCommit { + c.configMu.RLock() + defer c.configMu.RUnlock() + return c.gasPriceEstimator +} + +// Do not change the JSON format of this struct without consulting with +// the RDD people first. +type CommitOffchainConfigV1_2_0 struct { + SourceFinalityDepth uint32 + DestFinalityDepth uint32 + GasPriceHeartBeat models.Duration + DAGasPriceDeviationPPB uint32 + ExecGasPriceDeviationPPB uint32 + TokenPriceHeartBeat models.Duration + TokenPriceDeviationPPB uint32 + MaxGasPrice uint64 + InflightCacheExpiry models.Duration +} + +func (c CommitOffchainConfigV1_2_0) Validate() error { + if c.SourceFinalityDepth == 0 { + return errors.New("must set SourceFinalityDepth") + } + if c.DestFinalityDepth == 0 { + return errors.New("must set DestFinalityDepth") + } + if c.GasPriceHeartBeat.Duration() == 0 { + return errors.New("must set GasPriceHeartBeat") + } + if c.DAGasPriceDeviationPPB == 0 { + return errors.New("must set DAGasPriceDeviationPPB") + } + if c.ExecGasPriceDeviationPPB == 0 { + return errors.New("must set ExecGasPriceDeviationPPB") + } + if c.TokenPriceHeartBeat.Duration() == 0 { + return errors.New("must set TokenPriceHeartBeat") + } + if c.TokenPriceDeviationPPB == 0 { + return errors.New("must set TokenPriceDeviationPPB") + } + if c.MaxGasPrice == 0 { + return errors.New("must set MaxGasPrice") + } + if c.InflightCacheExpiry.Duration() == 0 { + return errors.New("must set InflightCacheExpiry") + } + + return nil +} + +func (c *CommitStoreV1_2_0) ChangeConfig(onchainConfig []byte, offchainConfig []byte) (common.Address, error) { + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[CommitOnchainConfig](onchainConfig) + if err != nil { + return common.Address{}, err + } + + offchainConfigParsed, err := ccipconfig.DecodeOffchainConfig[CommitOffchainConfigV1_2_0](offchainConfig) + if err != nil { + return common.Address{}, err + } + c.configMu.Lock() + c.gasPriceEstimator = prices.NewDAGasPriceEstimator( + c.estimator, + big.NewInt(int64(offchainConfigParsed.MaxGasPrice)), + int64(offchainConfigParsed.ExecGasPriceDeviationPPB), + int64(offchainConfigParsed.DAGasPriceDeviationPPB), + ) + c.offchainConfig = CommitOffchainConfig{ + SourceFinalityDepth: offchainConfigParsed.SourceFinalityDepth, + GasPriceDeviationPPB: offchainConfigParsed.ExecGasPriceDeviationPPB, + TokenPriceDeviationPPB: offchainConfigParsed.TokenPriceDeviationPPB, + InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry.Duration(), + DestFinalityDepth: offchainConfigParsed.DestFinalityDepth, + } + c.configMu.Unlock() + + c.lggr.Infow("ChangeConfig", + "offchainConfig", offchainConfigParsed, + "onchainConfig", onchainConfigParsed, + ) + return onchainConfigParsed.PriceRegistry, nil +} + +func (c *CommitStoreV1_2_0) Close(qopts ...pg.QOpt) error { + return logpollerutil.UnregisterLpFilters(c.lp, c.filters, qopts...) +} + +func (c *CommitStoreV1_2_0) parseReport(log types.Log) (*CommitStoreReport, error) { + repAccepted, err := c.commitStore.ParseReportAccepted(log) + if err != nil { + return nil, err + } + // Translate to common struct. + var tokenPrices []TokenPrice + for _, tpu := range repAccepted.Report.PriceUpdates.TokenPriceUpdates { + tokenPrices = append(tokenPrices, TokenPrice{ + Token: tpu.SourceToken, + Value: tpu.UsdPerToken, + }) + } + var gasPrices []GasPrice + for _, tpu := range repAccepted.Report.PriceUpdates.GasPriceUpdates { + gasPrices = append(gasPrices, GasPrice{ + DestChainSelector: tpu.DestChainSelector, + Value: tpu.UsdPerUnitGas, + }) + } + + return &CommitStoreReport{ + TokenPrices: tokenPrices, + GasPrices: gasPrices, + MerkleRoot: repAccepted.Report.MerkleRoot, + Interval: CommitStoreInterval{Min: repAccepted.Report.Interval.Min, Max: repAccepted.Report.Interval.Max}, + }, nil +} + +func (c *CommitStoreV1_2_0) GetAcceptedCommitReportsGteSeqNum(ctx context.Context, seqNum uint64, confs int) ([]Event[CommitStoreReport], error) { + logs, err := c.lp.LogsDataWordGreaterThan( + c.reportAcceptedSig, + c.address, + c.reportAcceptedMaxSeqIndex, + logpoller.EvmWord(seqNum), + confs, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, err + } + + return parseLogs[CommitStoreReport]( + logs, + c.lggr, + c.parseReport, + ) +} + +func (c *CommitStoreV1_2_0) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, ts time.Time, confs int) ([]Event[CommitStoreReport], error) { + logs, err := c.lp.LogsCreatedAfter( + c.reportAcceptedSig, + c.address, + ts, + confs, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, err + } + + return parseLogs[CommitStoreReport]( + logs, + c.lggr, + c.parseReport, + ) +} + +func (c *CommitStoreV1_2_0) GetExpectedNextSequenceNumber(ctx context.Context) (uint64, error) { + return c.commitStore.GetExpectedNextSequenceNumber(&bind.CallOpts{Context: ctx}) +} + +func (c *CommitStoreV1_2_0) GetLatestPriceEpochAndRound(ctx context.Context) (uint64, error) { + return c.commitStore.GetLatestPriceEpochAndRound(&bind.CallOpts{Context: ctx}) +} + +func (c *CommitStoreV1_2_0) IsDown(ctx context.Context) (bool, error) { + unPausedAndHealthy, err := c.commitStore.IsUnpausedAndARMHealthy(&bind.CallOpts{Context: ctx}) + if err != nil { + // If we cannot read the state, assume the worst + c.lggr.Errorw("Unable to read CommitStore IsUnpausedAndARMHealthy", "err", err) + return true, nil + } + return !unPausedAndHealthy, nil +} + +func (c *CommitStoreV1_2_0) VerifyExecutionReport(ctx context.Context, report ExecReport) (bool, error) { + var hashes [][32]byte + for _, msg := range report.Messages { + hashes = append(hashes, msg.Hash) + } + res, err := c.commitStore.Verify(&bind.CallOpts{Context: ctx}, hashes, report.Proofs, report.ProofFlagBits) + if err != nil { + c.lggr.Errorw("Unable to call verify", "messages", report.Messages, "err", err) + return false, nil + } + // No timestamp, means failed to verify root. + if res.Cmp(big.NewInt(0)) == 0 { + c.lggr.Errorw("Root does not verify", "messages", report.Messages) + return false, nil + } + return true, nil +} + +func NewCommitStoreV1_2_0(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator) (*CommitStoreV1_2_0, error) { + commitStore, err := commit_store.NewCommitStore(addr, ec) + if err != nil { + return nil, err + } + commitStoreABI := abihelpers.MustParseABI(commit_store.CommitStoreABI) + eventSig := abihelpers.MustGetEventID(ReportAccepted, commitStoreABI) + commitReportArgs := abihelpers.MustGetEventInputs(ReportAccepted, commitStoreABI) + var filters = []logpoller.Filter{ + { + Name: logpoller.FilterName(EXEC_REPORT_ACCEPTS, addr.String()), + EventSigs: []common.Hash{eventSig}, + Addresses: []common.Address{addr}, + }, + } + if err := logpollerutil.RegisterLpFilters(lp, filters); err != nil { + return nil, err + } + return &CommitStoreV1_2_0{ + commitStore: commitStore, + address: addr, + lggr: lggr, + lp: lp, + estimator: estimator, + filters: filters, + commitReportArgs: commitReportArgs, + reportAcceptedSig: eventSig, + // offset || priceUpdatesOffset || minSeqNum || maxSeqNum || merkleRoot + reportAcceptedMaxSeqIndex: 3, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go new file mode 100644 index 0000000000..ff1ecff9fb --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/commit_store_v1_2_0_test.go @@ -0,0 +1,56 @@ +package ccipdata + +import ( + "math/big" + "math/rand" + "testing" + + "github.com/stretchr/testify/assert" + "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/utils" +) + +func TestCommitReportEncodingV_1_2_0(t *testing.T) { + report := CommitStoreReport{ + TokenPrices: []TokenPrice{ + { + Token: utils.RandomAddress(), + Value: big.NewInt(9e18), + }, + { + Token: utils.RandomAddress(), + Value: big.NewInt(1e18), + }, + }, + GasPrices: []GasPrice{ + { + DestChainSelector: rand.Uint64(), + Value: big.NewInt(2000e9), + }, + { + DestChainSelector: rand.Uint64(), + Value: big.NewInt(3000e9), + }, + }, + MerkleRoot: [32]byte{123}, + Interval: CommitStoreInterval{Min: 1, Max: 10}, + } + + lp := mocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + + c, err := NewCommitStoreV1_2_0(logger.TestLogger(t), randomAddress(), nil, lp, nil) + assert.NoError(t, err) + + encodedReport, err := c.EncodeCommitReport(report) + require.NoError(t, err) + assert.Greater(t, len(encodedReport), 0) + + decodedReport, err := c.DecodeCommitReport(encodedReport) + require.NoError(t, err) + require.Equal(t, report, decodedReport) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/logpoller.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/logpoller.go index e7d16c7d8a..cd38580af7 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/logpoller.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/logpoller.go @@ -2,16 +2,10 @@ package ccipdata import ( "context" - "fmt" - "math/big" "sync" - "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/rpc" - "github.com/pkg/errors" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -20,7 +14,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) @@ -43,258 +36,10 @@ func NewLogPollerReader(lp logpoller.LogPoller, lggr logger.Logger, client evmcl } } -func (c *LogPollerReader) GetSendRequestsGteSeqNum(ctx context.Context, onRampAddress common.Address, seqNum uint64, checkFinalityTags bool, confs int) (sendReqs []Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], err error) { - onRamp, err := c.loadOnRamp(onRampAddress) - if err != nil { - return nil, err - } - - if !checkFinalityTags { - logs, err2 := c.lp.LogsDataWordGreaterThan( - abihelpers.EventSignatures.SendRequested, - onRampAddress, - abihelpers.EventSignatures.SendRequestedSequenceNumberWord, - abihelpers.EvmWord(seqNum), - confs, - pg.WithParentCtx(ctx), - ) - if err2 != nil { - return nil, fmt.Errorf("logs data word greater than: %w", err2) - } - return parseLogs[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]( - logs, - c.lggr, - func(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested, error) { - return onRamp.ParseCCIPSendRequested(log) - }, - ) - } - - // If the chain is based on explicit finality we only examine logs less than or equal to the latest finalized block number. - // NOTE: there appears to be a bug in ethclient whereby BlockByNumber fails with "unsupported txtype" when trying to parse the block - // when querying L2s, headers however work. - // TODO (CCIP-778): Migrate to core finalized tags, below doesn't work for some chains e.g. Celo. - latestFinalizedHeader, err := c.client.HeaderByNumber( - ctx, - big.NewInt(rpc.FinalizedBlockNumber.Int64()), - ) - if err != nil { - return nil, err - } - - if latestFinalizedHeader == nil { - return nil, errors.New("latest finalized header is nil") - } - if latestFinalizedHeader.Number == nil { - return nil, errors.New("latest finalized number is nil") - } - logs, err := c.lp.LogsUntilBlockHashDataWordGreaterThan( - abihelpers.EventSignatures.SendRequested, - onRampAddress, - abihelpers.EventSignatures.SendRequestedSequenceNumberWord, - abihelpers.EvmWord(seqNum), - latestFinalizedHeader.Hash(), - pg.WithParentCtx(ctx), - ) - if err != nil { - return nil, fmt.Errorf("logs until block hash data word greater than: %w", err) - } - - return parseLogs[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]( - logs, - c.lggr, - func(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested, error) { - return onRamp.ParseCCIPSendRequested(log) - }, - ) -} - -func (c *LogPollerReader) GetSendRequestsBetweenSeqNums(ctx context.Context, onRampAddress common.Address, seqNumMin, seqNumMax uint64, confs int) ([]Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], error) { - onRamp, err := c.loadOnRamp(onRampAddress) - if err != nil { - return nil, err - } - - logs, err := c.lp.LogsDataWordRange( - abihelpers.EventSignatures.SendRequested, - onRampAddress, - abihelpers.EventSignatures.SendRequestedSequenceNumberWord, - logpoller.EvmWord(seqNumMin), - logpoller.EvmWord(seqNumMax), - confs, - pg.WithParentCtx(ctx)) - if err != nil { - return nil, err - } - - return parseLogs[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]( - logs, - c.lggr, - func(log types.Log) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested, error) { - return onRamp.ParseCCIPSendRequested(log) - }, - ) -} - -func (c *LogPollerReader) GetTokenPriceUpdatesCreatedAfter(ctx context.Context, priceRegistryAddress common.Address, ts time.Time, confs int) ([]Event[price_registry.PriceRegistryUsdPerTokenUpdated], error) { - priceRegistry, err := c.loadPriceRegistry(priceRegistryAddress) - if err != nil { - return nil, err - } - - logs, err := c.lp.LogsCreatedAfter( - abihelpers.EventSignatures.UsdPerTokenUpdated, - priceRegistryAddress, - ts, - confs, - pg.WithParentCtx(ctx), - ) - if err != nil { - return nil, err - } - - return parseLogs[price_registry.PriceRegistryUsdPerTokenUpdated]( - logs, - c.lggr, - func(log types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error) { - return priceRegistry.ParseUsdPerTokenUpdated(log) - }, - ) -} - -func (c *LogPollerReader) GetGasPriceUpdatesCreatedAfter(ctx context.Context, priceRegistryAddress common.Address, chainSelector uint64, ts time.Time, confs int) ([]Event[price_registry.PriceRegistryUsdPerUnitGasUpdated], error) { - priceRegistry, err := c.loadPriceRegistry(priceRegistryAddress) - if err != nil { - return nil, err - } - - logs, err := c.lp.IndexedLogsCreatedAfter( - abihelpers.EventSignatures.UsdPerUnitGasUpdated, - priceRegistryAddress, - 1, - []common.Hash{abihelpers.EvmWord(chainSelector)}, - ts, - confs, - pg.WithParentCtx(ctx), - ) - if err != nil { - return nil, err - } - - return parseLogs[price_registry.PriceRegistryUsdPerUnitGasUpdated]( - logs, - c.lggr, - func(log types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error) { - return priceRegistry.ParseUsdPerUnitGasUpdated(log) - }, - ) -} - -func (c *LogPollerReader) GetExecutionStateChangesBetweenSeqNums(ctx context.Context, offRampAddress common.Address, seqNumMin, seqNumMax uint64, confs int) ([]Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged], error) { - offRamp, err := c.loadOffRamp(offRampAddress) - if err != nil { - return nil, err - } - - logs, err := c.lp.IndexedLogsTopicRange( - abihelpers.EventSignatures.ExecutionStateChanged, - offRampAddress, - abihelpers.EventSignatures.ExecutionStateChangedSequenceNumberIndex, - logpoller.EvmWord(seqNumMin), - logpoller.EvmWord(seqNumMax), - confs, - pg.WithParentCtx(ctx), - ) - if err != nil { - return nil, err - } - - return parseLogs[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged]( - logs, - c.lggr, - func(log types.Log) (*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged, error) { - return offRamp.ParseExecutionStateChanged(log) - }, - ) -} - -func (c *LogPollerReader) GetLastUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, txHash common.Hash) ([]byte, error) { - logs, err := c.lp.IndexedLogsByTxHash( - abihelpers.EventSignatures.USDCMessageSent, - txHash, - pg.WithParentCtx(ctx), - ) - if err != nil { - return nil, err - } - - for i := range logs { - current := logs[len(logs)-i-1] - if current.LogIndex < logIndex { - c.lggr.Infow("Found USDC message", "logIndex", current.LogIndex, "txHash", current.TxHash.Hex(), "data", hexutil.Encode(current.Data)) - return current.Data, nil - } - } - return nil, errors.Errorf("no USDC message found prior to log index %d in tx %s", logIndex, txHash.Hex()) -} - func (c *LogPollerReader) LatestBlock(ctx context.Context) (int64, error) { return c.lp.LatestBlock(pg.WithParentCtx(ctx)) } -func (c *LogPollerReader) GetAcceptedCommitReportsGteSeqNum(ctx context.Context, commitStoreAddress common.Address, seqNum uint64, confs int) ([]Event[commit_store.CommitStoreReportAccepted], error) { - commitStore, err := c.loadCommitStore(commitStoreAddress) - if err != nil { - return nil, err - } - - logs, err := c.lp.LogsDataWordGreaterThan( - abihelpers.EventSignatures.ReportAccepted, - commitStoreAddress, - abihelpers.EventSignatures.ReportAcceptedMaxSequenceNumberWord, - logpoller.EvmWord(seqNum), - confs, - pg.WithParentCtx(ctx), - ) - if err != nil { - return nil, err - } - - return parseLogs[commit_store.CommitStoreReportAccepted]( - logs, - c.lggr, - func(log types.Log) (*commit_store.CommitStoreReportAccepted, error) { - return commitStore.ParseReportAccepted(log) - }, - ) -} - -func (c *LogPollerReader) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, commitStoreAddress common.Address, ts time.Time, confs int) ([]Event[commit_store.CommitStoreReportAccepted], error) { - commitStore, err := c.loadCommitStore(commitStoreAddress) - if err != nil { - return nil, err - } - - logs, err := c.lp.LogsCreatedAfter( - abihelpers.EventSignatures.ReportAccepted, - commitStoreAddress, - ts, - confs, - pg.WithParentCtx(ctx), - ) - if err != nil { - return nil, err - } - - return parseLogs[commit_store.CommitStoreReportAccepted]( - logs, - c.lggr, - func(log types.Log) (*commit_store.CommitStoreReportAccepted, error) { - return commitStore.ParseReportAccepted(log) - }, - ) -} - func parseLogs[T any](logs []logpoller.Log, lggr logger.Logger, parseFunc func(log types.Log) (*T, error)) ([]Event[T], error) { reqs := make([]Event[T], 0, len(logs)) for _, log := range logs { @@ -302,9 +47,11 @@ func parseLogs[T any](logs []logpoller.Log, lggr logger.Logger, parseFunc func(l if err == nil { reqs = append(reqs, Event[T]{ Data: *data, - BlockMeta: BlockMeta{ + Meta: Meta{ BlockTimestamp: log.BlockTimestamp, BlockNumber: log.BlockNumber, + TxHash: log.TxHash, + LogIndex: uint(log.LogIndex), }, }) } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/logpoller_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/logpoller_test.go index 48e10c87e1..cfd5de87ec 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/logpoller_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/logpoller_test.go @@ -1,21 +1,15 @@ package ccipdata import ( - "context" "fmt" - "math/big" "testing" "time" "github.com/ethereum/go-ethereum/core/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/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -73,107 +67,3 @@ func Test_parseLogs(t *testing.T) { assert.Greater(t, ev.BlockTimestamp, time.Now().Add(-time.Minute)) } } - -func TestLogPollerClient_GetSendRequestsGteSeqNum(t *testing.T) { - onRampAddr := utils.RandomAddress() - seqNum := uint64(100) - confs := 4 - - t.Run("using confs", func(t *testing.T) { - lp := mocks.NewLogPoller(t) - lp.On("LogsDataWordGreaterThan", - abihelpers.EventSignatures.SendRequested, - onRampAddr, - abihelpers.EventSignatures.SendRequestedSequenceNumberWord, - abihelpers.EvmWord(seqNum), - confs, - mock.Anything, - ).Return([]logpoller.Log{}, nil) - - c := &LogPollerReader{lp: lp} - events, err := c.GetSendRequestsGteSeqNum( - context.Background(), - onRampAddr, - seqNum, - false, - confs, - ) - assert.NoError(t, err) - assert.Empty(t, events) - lp.AssertExpectations(t) - }) - - t.Run("using latest confirmed block", func(t *testing.T) { - h := &types.Header{Number: big.NewInt(100000)} - - lp := mocks.NewLogPoller(t) - lp.On("LogsUntilBlockHashDataWordGreaterThan", - abihelpers.EventSignatures.SendRequested, - onRampAddr, - abihelpers.EventSignatures.SendRequestedSequenceNumberWord, - abihelpers.EvmWord(seqNum), - h.Hash(), - mock.Anything, - ).Return([]logpoller.Log{}, nil) - - cl := evmClientMocks.NewClient(t) - cl.On("HeaderByNumber", mock.Anything, mock.Anything).Return(h, nil) - - c := &LogPollerReader{lp: lp, client: cl} - events, err := c.GetSendRequestsGteSeqNum( - context.Background(), - onRampAddr, - seqNum, - true, - confs, - ) - assert.NoError(t, err) - assert.Empty(t, events) - lp.AssertExpectations(t) - cl.AssertExpectations(t) - }) -} - -func TestLogPollerClient_GetLastUSDCMessagePriorToLogIndexInTx(t *testing.T) { - txHash := utils.RandomAddress().Hash() - ccipLogIndex := int64(100) - - expectedData := []byte("-1") - - t.Run("multiple found", func(t *testing.T) { - lp := mocks.NewLogPoller(t) - lp.On("IndexedLogsByTxHash", - abihelpers.EventSignatures.USDCMessageSent, - txHash, - mock.Anything, - ).Return([]logpoller.Log{ - {LogIndex: ccipLogIndex - 2, Data: []byte("-2")}, - {LogIndex: ccipLogIndex - 1, Data: expectedData}, - {LogIndex: ccipLogIndex, Data: []byte("0")}, - {LogIndex: ccipLogIndex + 1, Data: []byte("1")}, - }, nil) - - c := &LogPollerReader{lp: lp, lggr: logger.TestLogger(t)} - usdcMessageData, err := c.GetLastUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, txHash) - assert.NoError(t, err) - assert.Equal(t, expectedData, usdcMessageData) - - lp.AssertExpectations(t) - }) - - t.Run("none found", func(t *testing.T) { - lp := mocks.NewLogPoller(t) - lp.On("IndexedLogsByTxHash", - abihelpers.EventSignatures.USDCMessageSent, - txHash, - mock.Anything, - ).Return([]logpoller.Log{}, nil) - - c := &LogPollerReader{lp: lp} - usdcMessageData, err := c.GetLastUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, txHash) - assert.Errorf(t, err, fmt.Sprintf("no USDC message found prior to log index %d in tx %s", ccipLogIndex, txHash.Hex())) - assert.Nil(t, usdcMessageData) - - lp.AssertExpectations(t) - }) -} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/mock.go deleted file mode 100644 index 5790158c37..0000000000 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/mock.go +++ /dev/null @@ -1,272 +0,0 @@ -// Code generated by mockery v2.28.1. DO NOT EDIT. - -package ccipdata - -import ( - common "github.com/ethereum/go-ethereum/common" - commit_store "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - - context "context" - - evm_2_evm_offramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - - evm_2_evm_onramp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - - mock "github.com/stretchr/testify/mock" - - price_registry "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" - - time "time" -) - -// MockReader is an autogenerated mock type for the Reader type -type MockReader struct { - mock.Mock -} - -// GetAcceptedCommitReportsGteSeqNum provides a mock function with given fields: ctx, commitStoreAddress, seqNum, confs -func (_m *MockReader) GetAcceptedCommitReportsGteSeqNum(ctx context.Context, commitStoreAddress common.Address, seqNum uint64, confs int) ([]Event[commit_store.CommitStoreReportAccepted], error) { - ret := _m.Called(ctx, commitStoreAddress, seqNum, confs) - - var r0 []Event[commit_store.CommitStoreReportAccepted] - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, int) ([]Event[commit_store.CommitStoreReportAccepted], error)); ok { - return rf(ctx, commitStoreAddress, seqNum, confs) - } - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, int) []Event[commit_store.CommitStoreReportAccepted]); ok { - r0 = rf(ctx, commitStoreAddress, seqNum, confs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]Event[commit_store.CommitStoreReportAccepted]) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, common.Address, uint64, int) error); ok { - r1 = rf(ctx, commitStoreAddress, seqNum, confs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetAcceptedCommitReportsGteTimestamp provides a mock function with given fields: ctx, commitStoreAddress, ts, confs -func (_m *MockReader) GetAcceptedCommitReportsGteTimestamp(ctx context.Context, commitStoreAddress common.Address, ts time.Time, confs int) ([]Event[commit_store.CommitStoreReportAccepted], error) { - ret := _m.Called(ctx, commitStoreAddress, ts, confs) - - var r0 []Event[commit_store.CommitStoreReportAccepted] - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, common.Address, time.Time, int) ([]Event[commit_store.CommitStoreReportAccepted], error)); ok { - return rf(ctx, commitStoreAddress, ts, confs) - } - if rf, ok := ret.Get(0).(func(context.Context, common.Address, time.Time, int) []Event[commit_store.CommitStoreReportAccepted]); ok { - r0 = rf(ctx, commitStoreAddress, ts, confs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]Event[commit_store.CommitStoreReportAccepted]) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, common.Address, time.Time, int) error); ok { - r1 = rf(ctx, commitStoreAddress, ts, confs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetExecutionStateChangesBetweenSeqNums provides a mock function with given fields: ctx, offRamp, seqNumMin, seqNumMax, confs -func (_m *MockReader) GetExecutionStateChangesBetweenSeqNums(ctx context.Context, offRamp common.Address, seqNumMin uint64, seqNumMax uint64, confs int) ([]Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged], error) { - ret := _m.Called(ctx, offRamp, seqNumMin, seqNumMax, confs) - - var r0 []Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged] - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, uint64, int) ([]Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged], error)); ok { - return rf(ctx, offRamp, seqNumMin, seqNumMax, confs) - } - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, uint64, int) []Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged]); ok { - r0 = rf(ctx, offRamp, seqNumMin, seqNumMax, confs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged]) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, common.Address, uint64, uint64, int) error); ok { - r1 = rf(ctx, offRamp, seqNumMin, seqNumMax, confs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetGasPriceUpdatesCreatedAfter provides a mock function with given fields: ctx, priceRegistry, chainSelector, ts, confs -func (_m *MockReader) GetGasPriceUpdatesCreatedAfter(ctx context.Context, priceRegistry common.Address, chainSelector uint64, ts time.Time, confs int) ([]Event[price_registry.PriceRegistryUsdPerUnitGasUpdated], error) { - ret := _m.Called(ctx, priceRegistry, chainSelector, ts, confs) - - var r0 []Event[price_registry.PriceRegistryUsdPerUnitGasUpdated] - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, time.Time, int) ([]Event[price_registry.PriceRegistryUsdPerUnitGasUpdated], error)); ok { - return rf(ctx, priceRegistry, chainSelector, ts, confs) - } - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, time.Time, int) []Event[price_registry.PriceRegistryUsdPerUnitGasUpdated]); ok { - r0 = rf(ctx, priceRegistry, chainSelector, ts, confs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]Event[price_registry.PriceRegistryUsdPerUnitGasUpdated]) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, common.Address, uint64, time.Time, int) error); ok { - r1 = rf(ctx, priceRegistry, chainSelector, ts, confs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetLastUSDCMessagePriorToLogIndexInTx provides a mock function with given fields: ctx, logIndex, txHash -func (_m *MockReader) GetLastUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, txHash common.Hash) ([]byte, error) { - ret := _m.Called(ctx, logIndex, txHash) - - var r0 []byte - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, int64, common.Hash) ([]byte, error)); ok { - return rf(ctx, logIndex, txHash) - } - if rf, ok := ret.Get(0).(func(context.Context, int64, common.Hash) []byte); ok { - r0 = rf(ctx, logIndex, txHash) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]byte) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, int64, common.Hash) error); ok { - r1 = rf(ctx, logIndex, txHash) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetSendRequestsBetweenSeqNums provides a mock function with given fields: ctx, onRamp, seqNumMin, seqNumMax, confs -func (_m *MockReader) GetSendRequestsBetweenSeqNums(ctx context.Context, onRamp common.Address, seqNumMin uint64, seqNumMax uint64, confs int) ([]Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], error) { - ret := _m.Called(ctx, onRamp, seqNumMin, seqNumMax, confs) - - var r0 []Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested] - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, uint64, int) ([]Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], error)); ok { - return rf(ctx, onRamp, seqNumMin, seqNumMax, confs) - } - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, uint64, int) []Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]); ok { - r0 = rf(ctx, onRamp, seqNumMin, seqNumMax, confs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, common.Address, uint64, uint64, int) error); ok { - r1 = rf(ctx, onRamp, seqNumMin, seqNumMax, confs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetSendRequestsGteSeqNum provides a mock function with given fields: ctx, onRamp, seqNum, checkFinalityTags, confs -func (_m *MockReader) GetSendRequestsGteSeqNum(ctx context.Context, onRamp common.Address, seqNum uint64, checkFinalityTags bool, confs int) ([]Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], error) { - ret := _m.Called(ctx, onRamp, seqNum, checkFinalityTags, confs) - - var r0 []Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested] - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, bool, int) ([]Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], error)); ok { - return rf(ctx, onRamp, seqNum, checkFinalityTags, confs) - } - if rf, ok := ret.Get(0).(func(context.Context, common.Address, uint64, bool, int) []Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]); ok { - r0 = rf(ctx, onRamp, seqNum, checkFinalityTags, confs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, common.Address, uint64, bool, int) error); ok { - r1 = rf(ctx, onRamp, seqNum, checkFinalityTags, confs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetTokenPriceUpdatesCreatedAfter provides a mock function with given fields: ctx, priceRegistry, ts, confs -func (_m *MockReader) GetTokenPriceUpdatesCreatedAfter(ctx context.Context, priceRegistry common.Address, ts time.Time, confs int) ([]Event[price_registry.PriceRegistryUsdPerTokenUpdated], error) { - ret := _m.Called(ctx, priceRegistry, ts, confs) - - var r0 []Event[price_registry.PriceRegistryUsdPerTokenUpdated] - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, common.Address, time.Time, int) ([]Event[price_registry.PriceRegistryUsdPerTokenUpdated], error)); ok { - return rf(ctx, priceRegistry, ts, confs) - } - if rf, ok := ret.Get(0).(func(context.Context, common.Address, time.Time, int) []Event[price_registry.PriceRegistryUsdPerTokenUpdated]); ok { - r0 = rf(ctx, priceRegistry, ts, confs) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]Event[price_registry.PriceRegistryUsdPerTokenUpdated]) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, common.Address, time.Time, int) error); ok { - r1 = rf(ctx, priceRegistry, ts, confs) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// LatestBlock provides a mock function with given fields: ctx -func (_m *MockReader) LatestBlock(ctx context.Context) (int64, error) { - ret := _m.Called(ctx) - - var r0 int64 - var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (int64, error)); ok { - return rf(ctx) - } - if rf, ok := ret.Get(0).(func(context.Context) int64); ok { - r0 = rf(ctx) - } else { - r0 = ret.Get(0).(int64) - } - - if rf, ok := ret.Get(1).(func(context.Context) error); ok { - r1 = rf(ctx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -type mockConstructorTestingTNewMockReader interface { - mock.TestingT - Cleanup(func()) -} - -// NewMockReader creates a new instance of MockReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewMockReader(t mockConstructorTestingTNewMockReader) *MockReader { - mock := &MockReader{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go new file mode 100644 index 0000000000..42f6159704 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader.go @@ -0,0 +1,211 @@ +package ccipdata + +import ( + "context" + "math/big" + "time" + + "github.com/Masterminds/semver/v3" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + "github.com/smartcontractkit/chainlink/v2/core/store/models" +) + +const ( + ManuallyExecute = "manuallyExecute" +) + +// Do not change the JSON format of this struct without consulting with +// the RDD people first. +type ExecOffchainConfig struct { + SourceFinalityDepth uint32 + DestOptimisticConfirmations uint32 + DestFinalityDepth uint32 + BatchGasLimit uint32 + RelativeBoostPerWaitHour float64 + MaxGasPrice uint64 + InflightCacheExpiry models.Duration + RootSnoozeTime models.Duration +} + +func (c ExecOffchainConfig) Validate() error { + if c.SourceFinalityDepth == 0 { + return errors.New("must set SourceFinalityDepth") + } + if c.DestFinalityDepth == 0 { + return errors.New("must set DestFinalityDepth") + } + if c.DestOptimisticConfirmations == 0 { + return errors.New("must set DestOptimisticConfirmations") + } + if c.BatchGasLimit == 0 { + return errors.New("must set BatchGasLimit") + } + if c.RelativeBoostPerWaitHour == 0 { + return errors.New("must set RelativeBoostPerWaitHour") + } + if c.MaxGasPrice == 0 { + return errors.New("must set MaxGasPrice") + } + if c.InflightCacheExpiry.Duration() == 0 { + return errors.New("must set InflightCacheExpiry") + } + if c.RootSnoozeTime.Duration() == 0 { + return errors.New("must set RootSnoozeTime") + } + + return nil +} + +type ExecOnchainConfig struct { + PermissionLessExecutionThresholdSeconds time.Duration +} + +type ExecOnchainConfigV1_0_0 evm_2_evm_offramp.EVM2EVMOffRampDynamicConfig + +func (d ExecOnchainConfigV1_0_0) AbiString() string { + return ` + [ + { + "components": [ + {"name": "permissionLessExecutionThresholdSeconds", "type": "uint32"}, + {"name": "router", "type": "address"}, + {"name": "priceRegistry", "type": "address"}, + {"name": "maxTokensLength", "type": "uint16"}, + {"name": "maxDataSize", "type": "uint32"} + ], + "type": "tuple" + } + ]` +} + +func (d ExecOnchainConfigV1_0_0) Validate() error { + if d.PermissionLessExecutionThresholdSeconds == 0 { + return errors.New("must set PermissionLessExecutionThresholdSeconds") + } + if d.Router == (common.Address{}) { + return errors.New("must set Router address") + } + if d.PriceRegistry == (common.Address{}) { + return errors.New("must set PriceRegistry address") + } + if d.MaxTokensLength == 0 { + return errors.New("must set MaxTokensLength") + } + if d.MaxDataSize == 0 { + return errors.New("must set MaxDataSize") + } + return nil +} + +func (d ExecOnchainConfigV1_0_0) PermissionLessExecutionThresholdDuration() time.Duration { + return time.Duration(d.PermissionLessExecutionThresholdSeconds) * time.Second +} + +type ExecutionStateChanged struct { + SequenceNumber uint64 +} + +type ExecReport struct { + Messages []internal.EVM2EVMMessage + OffchainTokenData [][][]byte + Proofs [][32]byte + ProofFlagBits *big.Int +} + +//go:generate mockery --quiet --name OffRampReader --output . --filename offramp_reader_mock.go --inpackage --case=underscore +type OffRampReader interface { + Closer + // Will error if messages are not a compatible verion + EncodeExecutionReport(report ExecReport) ([]byte, error) + DecodeExecutionReport(report []byte) (ExecReport, error) + // GetExecutionStateChangesBetweenSeqNums returns all the execution state change events for the provided message sequence numbers (inclusive). + GetExecutionStateChangesBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, confs int) ([]Event[ExecutionStateChanged], error) + GetDestinationTokens(ctx context.Context) ([]common.Address, error) + GetPoolByDestToken(ctx context.Context, address common.Address) (common.Address, error) + GetDestinationToken(ctx context.Context, address common.Address) (common.Address, error) + GetSupportedTokens(ctx context.Context) ([]common.Address, error) + Address() common.Address + // TODO Needed for caching, maybe caching should move behind the readers? + TokenEvents() []common.Hash + // Notifies the reader that the config has changed onchain + ChangeConfig(onchainConfig []byte, offchainConfig []byte) (common.Address, common.Address, error) + OffchainConfig() ExecOffchainConfig + OnchainConfig() ExecOnchainConfig + GasPriceEstimator() prices.GasPriceEstimatorExec +} + +// MessageExecutionState defines the execution states of CCIP messages. +type MessageExecutionState uint8 + +const ( + ExecutionStateUntouched MessageExecutionState = iota + ExecutionStateInProgress + ExecutionStateSuccess + ExecutionStateFailure +) + +func NewOffRampReader(lggr logger.Logger, addr common.Address, destClient client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator) (OffRampReader, error) { + _, version, err := ccipconfig.TypeAndVersion(addr, destClient) + if err != nil { + return nil, err + } + switch version.String() { + case v1_0_0, v1_1_0: + return NewOffRampV1_0_0(lggr, addr, destClient, lp, estimator) + case v1_2_0: + return NewOffRampV1_2_0(lggr, addr, destClient, lp, estimator) + default: + return nil, errors.Errorf("unsupported offramp version %v", version.String()) + } + // TODO can validate it points to the correct onramp version using srcClinet +} + +func ExecReportToEthTxMeta(typ ccipconfig.ContractType, ver semver.Version) (func(report []byte) (*txmgr.TxMeta, error), error) { + if typ != ccipconfig.EVM2EVMOffRamp { + return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOffRamp, typ) + } + switch ver.String() { + case v1_0_0, v1_1_0, v1_2_0: + // ABI remains the same across all offramp versions. + offRampABI := abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI) + return func(report []byte) (*txmgr.TxMeta, error) { + execReport, err := decodeExecReportV1_0_0(abihelpers.MustGetMethodInputs(ManuallyExecute, offRampABI)[:1], report) + if err != nil { + return nil, err + } + return execReportToEthTxMeta(execReport) + }, nil + default: + return nil, errors.Errorf("got unexpected version %v", ver.String()) + } +} + +func EncodeExecutionReport(report ExecReport) ([]byte, error) { + offRampABI := abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI) + return encodeExecutionReportV1_0_0(abihelpers.MustGetMethodInputs(ManuallyExecute, offRampABI)[:1], report) + // TODO: 1.2 will split +} + +func execReportToEthTxMeta(execReport ExecReport) (*txmgr.TxMeta, error) { + msgIDs := make([]string, len(execReport.Messages)) + for i, msg := range execReport.Messages { + msgIDs[i] = hexutil.Encode(msg.MessageId[:]) + } + + return &txmgr.TxMeta{ + MessageIDs: msgIDs, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_mock.go new file mode 100644 index 0000000000..643a2b8ced --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_mock.go @@ -0,0 +1,346 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package ccipdata + +import ( + context "context" + + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" + + prices "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +// MockOffRampReader is an autogenerated mock type for the OffRampReader type +type MockOffRampReader struct { + mock.Mock +} + +// Address provides a mock function with given fields: +func (_m *MockOffRampReader) Address() common.Address { + ret := _m.Called() + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// ChangeConfig provides a mock function with given fields: onchainConfig, offchainConfig +func (_m *MockOffRampReader) ChangeConfig(onchainConfig []byte, offchainConfig []byte) (common.Address, common.Address, error) { + ret := _m.Called(onchainConfig, offchainConfig) + + var r0 common.Address + var r1 common.Address + var r2 error + if rf, ok := ret.Get(0).(func([]byte, []byte) (common.Address, common.Address, error)); ok { + return rf(onchainConfig, offchainConfig) + } + if rf, ok := ret.Get(0).(func([]byte, []byte) common.Address); ok { + r0 = rf(onchainConfig, offchainConfig) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func([]byte, []byte) common.Address); ok { + r1 = rf(onchainConfig, offchainConfig) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(common.Address) + } + } + + if rf, ok := ret.Get(2).(func([]byte, []byte) error); ok { + r2 = rf(onchainConfig, offchainConfig) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// Close provides a mock function with given fields: qopts +func (_m *MockOffRampReader) Close(qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 error + if rf, ok := ret.Get(0).(func(...pg.QOpt) error); ok { + r0 = rf(qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DecodeExecutionReport provides a mock function with given fields: report +func (_m *MockOffRampReader) DecodeExecutionReport(report []byte) (ExecReport, error) { + ret := _m.Called(report) + + var r0 ExecReport + var r1 error + if rf, ok := ret.Get(0).(func([]byte) (ExecReport, error)); ok { + return rf(report) + } + if rf, ok := ret.Get(0).(func([]byte) ExecReport); ok { + r0 = rf(report) + } else { + r0 = ret.Get(0).(ExecReport) + } + + if rf, ok := ret.Get(1).(func([]byte) error); ok { + r1 = rf(report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EncodeExecutionReport provides a mock function with given fields: report +func (_m *MockOffRampReader) EncodeExecutionReport(report ExecReport) ([]byte, error) { + ret := _m.Called(report) + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(ExecReport) ([]byte, error)); ok { + return rf(report) + } + if rf, ok := ret.Get(0).(func(ExecReport) []byte); ok { + r0 = rf(report) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(ExecReport) error); ok { + r1 = rf(report) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GasPriceEstimator provides a mock function with given fields: +func (_m *MockOffRampReader) GasPriceEstimator() prices.GasPriceEstimatorExec { + ret := _m.Called() + + var r0 prices.GasPriceEstimatorExec + if rf, ok := ret.Get(0).(func() prices.GasPriceEstimatorExec); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(prices.GasPriceEstimatorExec) + } + } + + return r0 +} + +// GetDestinationToken provides a mock function with given fields: ctx, address +func (_m *MockOffRampReader) GetDestinationToken(ctx context.Context, address common.Address) (common.Address, error) { + ret := _m.Called(ctx, address) + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address) (common.Address, error)); ok { + return rf(ctx, address) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address) common.Address); ok { + r0 = rf(ctx, address) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address) error); ok { + r1 = rf(ctx, address) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetDestinationTokens provides a mock function with given fields: ctx +func (_m *MockOffRampReader) GetDestinationTokens(ctx context.Context) ([]common.Address, error) { + ret := _m.Called(ctx) + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]common.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []common.Address); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetExecutionStateChangesBetweenSeqNums provides a mock function with given fields: ctx, seqNumMin, seqNumMax, confs +func (_m *MockOffRampReader) GetExecutionStateChangesBetweenSeqNums(ctx context.Context, seqNumMin uint64, seqNumMax uint64, confs int) ([]Event[ExecutionStateChanged], error) { + ret := _m.Called(ctx, seqNumMin, seqNumMax, confs) + + var r0 []Event[ExecutionStateChanged] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, int) ([]Event[ExecutionStateChanged], error)); ok { + return rf(ctx, seqNumMin, seqNumMax, confs) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, int) []Event[ExecutionStateChanged]); ok { + r0 = rf(ctx, seqNumMin, seqNumMax, confs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]Event[ExecutionStateChanged]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, uint64, int) error); ok { + r1 = rf(ctx, seqNumMin, seqNumMax, confs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPoolByDestToken provides a mock function with given fields: ctx, address +func (_m *MockOffRampReader) GetPoolByDestToken(ctx context.Context, address common.Address) (common.Address, error) { + ret := _m.Called(ctx, address) + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, common.Address) (common.Address, error)); ok { + return rf(ctx, address) + } + if rf, ok := ret.Get(0).(func(context.Context, common.Address) common.Address); ok { + r0 = rf(ctx, address) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, common.Address) error); ok { + r1 = rf(ctx, address) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetSupportedTokens provides a mock function with given fields: ctx +func (_m *MockOffRampReader) GetSupportedTokens(ctx context.Context) ([]common.Address, error) { + ret := _m.Called(ctx) + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]common.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []common.Address); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// OffchainConfig provides a mock function with given fields: +func (_m *MockOffRampReader) OffchainConfig() ExecOffchainConfig { + ret := _m.Called() + + var r0 ExecOffchainConfig + if rf, ok := ret.Get(0).(func() ExecOffchainConfig); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(ExecOffchainConfig) + } + + return r0 +} + +// OnchainConfig provides a mock function with given fields: +func (_m *MockOffRampReader) OnchainConfig() ExecOnchainConfig { + ret := _m.Called() + + var r0 ExecOnchainConfig + if rf, ok := ret.Get(0).(func() ExecOnchainConfig); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(ExecOnchainConfig) + } + + return r0 +} + +// TokenEvents provides a mock function with given fields: +func (_m *MockOffRampReader) TokenEvents() []common.Hash { + ret := _m.Called() + + var r0 []common.Hash + if rf, ok := ret.Get(0).(func() []common.Hash); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Hash) + } + } + + return r0 +} + +type mockConstructorTestingTNewMockOffRampReader interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockOffRampReader creates a new instance of MockOffRampReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockOffRampReader(t mockConstructorTestingTNewMockOffRampReader) *MockOffRampReader { + mock := &MockOffRampReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/config/offchain_config_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go similarity index 56% rename from core/services/ocr2/plugins/ccip/config/offchain_config_test.go rename to core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go index 5edf21c176..8a83e33e2c 100644 --- a/core/services/ocr2/plugins/ccip/config/offchain_config_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_test.go @@ -1,70 +1,17 @@ -package config +package ccipdata import ( + "math/rand" "testing" "time" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) -func TestCommitOffchainConfig_Encoding(t *testing.T) { - tests := map[string]struct { - want CommitOffchainConfig - expectErr bool - }{ - "encodes and decodes config with all fields set": { - want: CommitOffchainConfig{ - SourceFinalityDepth: 3, - DestFinalityDepth: 3, - FeeUpdateHeartBeat: models.MustMakeDuration(1 * time.Hour), - FeeUpdateDeviationPPB: 5e7, - MaxGasPrice: 200e9, - InflightCacheExpiry: models.MustMakeDuration(23456 * time.Second), - }, - }, - "fails decoding when all fields present but with 0 values": { - want: CommitOffchainConfig{ - SourceFinalityDepth: 0, - DestFinalityDepth: 0, - FeeUpdateHeartBeat: models.MustMakeDuration(0), - FeeUpdateDeviationPPB: 0, - MaxGasPrice: 0, - InflightCacheExpiry: models.MustMakeDuration(0), - }, - expectErr: true, - }, - "fails decoding when all fields are missing": { - want: CommitOffchainConfig{}, - expectErr: true, - }, - "fails decoding when some fields are missing": { - want: CommitOffchainConfig{ - SourceFinalityDepth: 3, - FeeUpdateHeartBeat: models.MustMakeDuration(1 * time.Hour), - FeeUpdateDeviationPPB: 5e7, - MaxGasPrice: 200e9, - }, - expectErr: true, - }, - } - for name, tc := range tests { - t.Run(name, func(t *testing.T) { - encode, err := EncodeOffchainConfig(tc.want) - require.NoError(t, err) - got, err := DecodeOffchainConfig[CommitOffchainConfig](encode) - - if tc.expectErr { - require.ErrorContains(t, err, "must set") - } else { - require.NoError(t, err) - require.Equal(t, tc.want, got) - } - }) - } -} - func TestExecOffchainConfig_Encoding(t *testing.T) { tests := map[string]struct { want ExecOffchainConfig @@ -110,9 +57,9 @@ func TestExecOffchainConfig_Encoding(t *testing.T) { for name, tc := range tests { t.Run(name, func(t *testing.T) { exp := tc.want - encode, err := EncodeOffchainConfig(&exp) + encode, err := ccipconfig.EncodeOffchainConfig(&exp) require.NoError(t, err) - got, err := DecodeOffchainConfig[ExecOffchainConfig](encode) + got, err := ccipconfig.DecodeOffchainConfig[ExecOffchainConfig](encode) if tc.expectErr { require.ErrorContains(t, err, "must set") @@ -123,3 +70,44 @@ func TestExecOffchainConfig_Encoding(t *testing.T) { }) } } + +func TestExecOnchainConfig(t *testing.T) { + tests := []struct { + name string + want ExecOnchainConfigV1_0_0 + expectErr bool + }{ + { + name: "encodes and decodes config with all fields set", + want: ExecOnchainConfigV1_0_0{ + PermissionLessExecutionThresholdSeconds: rand.Uint32(), + Router: randomAddress(), + PriceRegistry: randomAddress(), + MaxTokensLength: uint16(rand.Uint32()), + MaxDataSize: rand.Uint32(), + }, + }, + { + name: "encodes and fails decoding config with missing fields", + want: ExecOnchainConfigV1_0_0{ + PermissionLessExecutionThresholdSeconds: rand.Uint32(), + MaxDataSize: rand.Uint32(), + }, + expectErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + encoded, err := abihelpers.EncodeAbiStruct(tt.want) + require.NoError(t, err) + + decoded, err := abihelpers.DecodeAbiStruct[ExecOnchainConfigV1_0_0](encoded) + if tt.expectErr { + require.ErrorContains(t, err, "must set") + } else { + require.NoError(t, err) + require.Equal(t, tt.want, decoded) + } + }) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go new file mode 100644 index 0000000000..14bbe7fbb0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_reader_v1_0_0_test.go @@ -0,0 +1,53 @@ +package ccipdata + +import ( + "math/big" + "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/client/mocks" + 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/ccip/internal" +) + +func TestExecutionReportEncoding(t *testing.T) { + // Note could consider some fancier testing here (fuzz/property) + // but I think that would essentially be testing geth's abi library + // as our encode/decode is a thin wrapper around that. + report := ExecReport{ + Messages: []internal.EVM2EVMMessage{}, + OffchainTokenData: [][][]byte{{}}, + Proofs: [][32]byte{testutils.Random32Byte()}, + ProofFlagBits: big.NewInt(133), + } + + lp := lpmocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + offRamp, err := NewOffRampV1_0_0(logger.TestLogger(t), randomAddress(), nil, lp, nil) + require.NoError(t, err) + + encodeExecutionReport, err := offRamp.EncodeExecutionReport(report) + require.NoError(t, err) + decodeCommitReport, err := offRamp.DecodeExecutionReport(encodeExecutionReport) + require.NoError(t, err) + require.Equal(t, report.Proofs, decodeCommitReport.Proofs) + // require.Equal(t, report, decodeCommitReport) // TODO: fails because some fields are not supported on v1_0_0 +} + +func TestOffRampFilters(t *testing.T) { + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { + c, err := NewOffRampV1_0_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) + require.NoError(t, err) + return c + }, 3) + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { + c, err := NewOffRampV1_2_0(logger.TestLogger(t), addr, new(mocks.Client), lp, nil) + require.NoError(t, err) + return c + }, 3) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go new file mode 100644 index 0000000000..2eb568ade5 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_0_0.go @@ -0,0 +1,333 @@ +package ccipdata + +import ( + "context" + "fmt" + "math/big" + "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/ethereum/go-ethereum/core/types" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +const ( + EXEC_EXECUTION_STATE_CHANGES = "Exec execution state changes" + EXEC_TOKEN_POOL_ADDED = "Token pool added" + EXEC_TOKEN_POOL_REMOVED = "Token pool removed" +) + +var ( + _ OffRampReader = &OffRampV1_0_0{} + ExecutionStateChangedEventV1_0_0 = abihelpers.MustGetEventID("ExecutionStateChanged", abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI)) + ExecutionStateChangedSeqNrV1_0_0 = 1 +) + +type OffRampV1_0_0 struct { + offRamp *evm_2_evm_offramp.EVM2EVMOffRamp + addr common.Address + lp logpoller.LogPoller + lggr logger.Logger + ec client.Client + filters []logpoller.Filter + estimator gas.EvmFeeEstimator + executionReportArgs abi.Arguments + eventIndex int + eventSig common.Hash + + // Dynamic config + configMu sync.RWMutex + gasPriceEstimator prices.GasPriceEstimatorExec + offchainConfig ExecOffchainConfig + onchainConfig ExecOnchainConfig +} + +func (o *OffRampV1_0_0) GetDestinationToken(ctx context.Context, address common.Address) (common.Address, error) { + return o.offRamp.GetDestinationToken(&bind.CallOpts{Context: ctx}, address) +} + +func (o *OffRampV1_0_0) GetSupportedTokens(ctx context.Context) ([]common.Address, error) { + return o.offRamp.GetSupportedTokens(&bind.CallOpts{Context: ctx}) +} + +func (o *OffRampV1_0_0) GetPoolByDestToken(ctx context.Context, address common.Address) (common.Address, error) { + return o.offRamp.GetPoolByDestToken(&bind.CallOpts{Context: ctx}, address) +} + +func (o *OffRampV1_0_0) OffchainConfig() ExecOffchainConfig { + o.configMu.RLock() + defer o.configMu.RUnlock() + return o.offchainConfig +} + +func (o *OffRampV1_0_0) OnchainConfig() ExecOnchainConfig { + o.configMu.RLock() + defer o.configMu.RUnlock() + return o.onchainConfig +} + +func (o *OffRampV1_0_0) GasPriceEstimator() prices.GasPriceEstimatorExec { + o.configMu.RLock() + defer o.configMu.RUnlock() + return o.gasPriceEstimator +} + +func (o *OffRampV1_0_0) Address() common.Address { + return o.addr +} + +func (o *OffRampV1_0_0) ChangeConfig(onchainConfig []byte, offchainConfig []byte) (common.Address, common.Address, error) { + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ExecOnchainConfigV1_0_0](onchainConfig) + if err != nil { + return common.Address{}, common.Address{}, err + } + + offchainConfigParsed, err := ccipconfig.DecodeOffchainConfig[ExecOffchainConfig](offchainConfig) + if err != nil { + return common.Address{}, common.Address{}, err + } + destRouter, err := router.NewRouter(onchainConfigParsed.Router, o.ec) + if err != nil { + return common.Address{}, common.Address{}, err + } + destWrappedNative, err := destRouter.GetWrappedNative(nil) + if err != nil { + return common.Address{}, common.Address{}, err + } + o.configMu.Lock() + o.offchainConfig = ExecOffchainConfig{ + SourceFinalityDepth: offchainConfigParsed.SourceFinalityDepth, + DestFinalityDepth: offchainConfigParsed.DestFinalityDepth, + DestOptimisticConfirmations: offchainConfigParsed.DestOptimisticConfirmations, + BatchGasLimit: offchainConfigParsed.BatchGasLimit, + RelativeBoostPerWaitHour: offchainConfigParsed.RelativeBoostPerWaitHour, + MaxGasPrice: offchainConfigParsed.MaxGasPrice, + InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry, + RootSnoozeTime: offchainConfigParsed.RootSnoozeTime, + } + o.onchainConfig = ExecOnchainConfig{PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds)} + o.gasPriceEstimator = prices.NewExecGasPriceEstimator(o.estimator, big.NewInt(int64(offchainConfigParsed.MaxGasPrice)), 0) + o.configMu.Unlock() + + o.lggr.Infow("Starting exec plugin", + "offchainConfig", onchainConfigParsed, + "onchainConfig", offchainConfigParsed) + return onchainConfigParsed.PriceRegistry, destWrappedNative, nil +} + +func (o *OffRampV1_0_0) GetDestinationTokens(ctx context.Context) ([]common.Address, error) { + return o.offRamp.GetDestinationTokens(&bind.CallOpts{Context: ctx}) +} + +func (o *OffRampV1_0_0) Close(qopts ...pg.QOpt) error { + return logpollerutil.UnregisterLpFilters(o.lp, o.filters, qopts...) +} + +func (o *OffRampV1_0_0) GetExecutionStateChangesBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, confs int) ([]Event[ExecutionStateChanged], error) { + logs, err := o.lp.IndexedLogsTopicRange( + o.eventSig, + o.addr, + o.eventIndex, + logpoller.EvmWord(seqNumMin), + logpoller.EvmWord(seqNumMax), + confs, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, err + } + + return parseLogs[ExecutionStateChanged]( + logs, + o.lggr, + func(log types.Log) (*ExecutionStateChanged, error) { + sc, err := o.offRamp.ParseExecutionStateChanged(log) + if err != nil { + return nil, err + } + return &ExecutionStateChanged{SequenceNumber: sc.SequenceNumber}, nil + }, + ) +} + +func encodeExecutionReportV1_0_0(args abi.Arguments, report ExecReport) ([]byte, error) { + var msgs []evm_2_evm_offramp.InternalEVM2EVMMessage + for _, msg := range report.Messages { + var ta []evm_2_evm_offramp.ClientEVMTokenAmount + for _, tokenAndAmount := range msg.TokenAmounts { + ta = append(ta, evm_2_evm_offramp.ClientEVMTokenAmount{ + Token: tokenAndAmount.Token, + Amount: tokenAndAmount.Amount, + }) + } + msgs = append(msgs, evm_2_evm_offramp.InternalEVM2EVMMessage{ + SourceChainSelector: msg.SourceChainSelector, + Sender: msg.Sender, + Receiver: msg.Receiver, + SequenceNumber: msg.SequenceNumber, + GasLimit: msg.GasLimit, + Strict: msg.Strict, + Nonce: msg.Nonce, + FeeToken: msg.FeeToken, + FeeTokenAmount: msg.FeeTokenAmount, + Data: msg.Data, + TokenAmounts: ta, + SourceTokenData: msg.SourceTokenData, + MessageId: msg.MessageId, + }) + } + + rep := evm_2_evm_offramp.InternalExecutionReport{ + Messages: msgs, + OffchainTokenData: report.OffchainTokenData, + Proofs: report.Proofs, + ProofFlagBits: report.ProofFlagBits, + } + return args.PackValues([]interface{}{&rep}) +} + +func (o *OffRampV1_0_0) EncodeExecutionReport(report ExecReport) ([]byte, error) { + return encodeExecutionReportV1_0_0(o.executionReportArgs, report) +} + +func decodeExecReportV1_0_0(args abi.Arguments, report []byte) (ExecReport, error) { + unpacked, err := args.Unpack(report) + if err != nil { + return ExecReport{}, err + } + if len(unpacked) == 0 { + return ExecReport{}, errors.New("assumptionViolation: expected at least one element") + } + // Must be anonymous struct here + erStruct, ok := unpacked[0].(struct { + Messages []struct { + SourceChainSelector uint64 `json:"sourceChainSelector"` + Sender common.Address `json:"sender"` + Receiver common.Address `json:"receiver"` + SequenceNumber uint64 `json:"sequenceNumber"` + GasLimit *big.Int `json:"gasLimit"` + Strict bool `json:"strict"` + Nonce uint64 `json:"nonce"` + FeeToken common.Address `json:"feeToken"` + FeeTokenAmount *big.Int `json:"feeTokenAmount"` + Data []uint8 `json:"data"` + TokenAmounts []struct { + Token common.Address `json:"token"` + Amount *big.Int `json:"amount"` + } `json:"tokenAmounts"` + SourceTokenData [][]byte `json:"sourceTokenData"` + MessageId [32]byte `json:"messageId"` + } `json:"messages"` + OffchainTokenData [][][]byte `json:"offchainTokenData"` + Proofs [][32]uint8 `json:"proofs"` + ProofFlagBits *big.Int `json:"proofFlagBits"` + }) + if !ok { + return ExecReport{}, fmt.Errorf("got %T", unpacked[0]) + } + var messages []internal.EVM2EVMMessage + for _, msg := range erStruct.Messages { + var tokensAndAmounts []internal.TokenAmount + for _, tokenAndAmount := range msg.TokenAmounts { + tokensAndAmounts = append(tokensAndAmounts, internal.TokenAmount{ + Token: tokenAndAmount.Token, + Amount: tokenAndAmount.Amount, + }) + } + messages = append(messages, internal.EVM2EVMMessage{ + SequenceNumber: msg.SequenceNumber, + GasLimit: msg.GasLimit, + Nonce: msg.Nonce, + MessageId: msg.MessageId, + SourceChainSelector: msg.SourceChainSelector, + Sender: msg.Sender, + Receiver: msg.Receiver, + Strict: msg.Strict, + FeeToken: msg.FeeToken, + FeeTokenAmount: msg.FeeTokenAmount, + Data: msg.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: msg.SourceTokenData, + // TODO: Not needed for plugins, but should be recomputed for consistency. + // Requires the offramp knowing about onramp version + Hash: [32]byte{}, + }) + } + + // Unpack will populate with big.Int{false, } for 0 values, + // which is different from the expected big.NewInt(0). Rebuild to the expected value for this case. + return ExecReport{ + Messages: messages, + OffchainTokenData: erStruct.OffchainTokenData, + Proofs: erStruct.Proofs, + ProofFlagBits: new(big.Int).SetBytes(erStruct.ProofFlagBits.Bytes()), + }, nil + +} + +func (o *OffRampV1_0_0) DecodeExecutionReport(report []byte) (ExecReport, error) { + return decodeExecReportV1_0_0(o.executionReportArgs, report) +} + +func (o *OffRampV1_0_0) TokenEvents() []common.Hash { + offRampABI := abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI) + return []common.Hash{abihelpers.MustGetEventID("PoolAdded", offRampABI), abihelpers.MustGetEventID("PoolRemoved", offRampABI)} +} + +func NewOffRampV1_0_0(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator) (*OffRampV1_0_0, error) { + offRamp, err := evm_2_evm_offramp.NewEVM2EVMOffRamp(addr, ec) + if err != nil { + return nil, err + } + offRampABI := abihelpers.MustParseABI(evm_2_evm_offramp.EVM2EVMOffRampABI) + executionStateChangedSequenceNumberIndex := 1 + executionReportArgs := abihelpers.MustGetMethodInputs("manuallyExecute", offRampABI)[:1] + var filters = []logpoller.Filter{ + { + Name: logpoller.FilterName(EXEC_EXECUTION_STATE_CHANGES, addr.String()), + EventSigs: []common.Hash{ExecutionStateChangedEventV1_0_0}, + Addresses: []common.Address{addr}, + }, + { + Name: logpoller.FilterName(EXEC_TOKEN_POOL_ADDED, addr.String()), + EventSigs: []common.Hash{abihelpers.MustGetEventID("PoolAdded", offRampABI)}, + Addresses: []common.Address{addr}, + }, + { + Name: logpoller.FilterName(EXEC_TOKEN_POOL_REMOVED, addr.String()), + EventSigs: []common.Hash{abihelpers.MustGetEventID("PoolRemoved", offRampABI)}, + Addresses: []common.Address{addr}, + }, + } + if err := logpollerutil.RegisterLpFilters(lp, filters); err != nil { + return nil, err + } + return &OffRampV1_0_0{ + offRamp: offRamp, + ec: ec, + addr: addr, + lggr: lggr, + lp: lp, + filters: filters, + estimator: estimator, + executionReportArgs: executionReportArgs, + eventSig: ExecutionStateChangedEventV1_0_0, + eventIndex: executionStateChangedSequenceNumberIndex, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go new file mode 100644 index 0000000000..1206ad3656 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/offramp_v1_2_0.go @@ -0,0 +1,97 @@ +package ccipdata + +import ( + "math/big" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/prices" +) + +var _ OffRampReader = &OffRampV1_2_0{} + +// In 1.2 we have a different estimator impl +type OffRampV1_2_0 struct { + *OffRampV1_0_0 + // Dynamic config + configMu sync.RWMutex + gasPriceEstimator prices.GasPriceEstimatorExec + offchainConfig ExecOffchainConfig + onchainConfig ExecOnchainConfig +} + +func (o *OffRampV1_2_0) ChangeConfig(onchainConfig []byte, offchainConfig []byte) (common.Address, common.Address, error) { + onchainConfigParsed, err := abihelpers.DecodeAbiStruct[ExecOnchainConfigV1_0_0](onchainConfig) + if err != nil { + return common.Address{}, common.Address{}, err + } + + offchainConfigParsed, err := ccipconfig.DecodeOffchainConfig[ExecOffchainConfig](offchainConfig) + if err != nil { + return common.Address{}, common.Address{}, err + } + destRouter, err := router.NewRouter(onchainConfigParsed.Router, o.ec) + if err != nil { + return common.Address{}, common.Address{}, err + } + destWrappedNative, err := destRouter.GetWrappedNative(nil) + if err != nil { + return common.Address{}, common.Address{}, err + } + o.configMu.Lock() + o.offchainConfig = ExecOffchainConfig{ + SourceFinalityDepth: offchainConfigParsed.SourceFinalityDepth, + DestFinalityDepth: offchainConfigParsed.DestFinalityDepth, + DestOptimisticConfirmations: offchainConfigParsed.DestOptimisticConfirmations, + BatchGasLimit: offchainConfigParsed.BatchGasLimit, + RelativeBoostPerWaitHour: offchainConfigParsed.RelativeBoostPerWaitHour, + MaxGasPrice: offchainConfigParsed.MaxGasPrice, + InflightCacheExpiry: offchainConfigParsed.InflightCacheExpiry, + RootSnoozeTime: offchainConfigParsed.RootSnoozeTime, + } + o.onchainConfig = ExecOnchainConfig{PermissionLessExecutionThresholdSeconds: time.Second * time.Duration(onchainConfigParsed.PermissionLessExecutionThresholdSeconds)} + o.gasPriceEstimator = prices.NewDAGasPriceEstimator(o.estimator, big.NewInt(int64(offchainConfigParsed.MaxGasPrice)), 0, 0) + o.configMu.Unlock() + o.lggr.Infow("Starting exec plugin", + "offchainConfig", onchainConfigParsed, + "onchainConfig", offchainConfigParsed) + return onchainConfigParsed.PriceRegistry, destWrappedNative, nil +} + +// TODO probably a way to reuse 1.0.0 +func (o *OffRampV1_2_0) OffchainConfig() ExecOffchainConfig { + o.configMu.RLock() + defer o.configMu.RUnlock() + return o.offchainConfig +} + +func (o *OffRampV1_2_0) OnchainConfig() ExecOnchainConfig { + o.configMu.RLock() + defer o.configMu.RUnlock() + return o.onchainConfig +} + +func (o *OffRampV1_2_0) GasPriceEstimator() prices.GasPriceEstimatorExec { + o.configMu.RLock() + defer o.configMu.RUnlock() + return o.gasPriceEstimator +} + +func NewOffRampV1_2_0(lggr logger.Logger, addr common.Address, ec client.Client, lp logpoller.LogPoller, estimator gas.EvmFeeEstimator) (*OffRampV1_2_0, error) { + v100, err := NewOffRampV1_0_0(lggr, addr, ec, lp, estimator) + if err != nil { + return nil, err + } + return &OffRampV1_2_0{ + OffRampV1_0_0: v100, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go new file mode 100644 index 0000000000..f09952008c --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader.go @@ -0,0 +1,79 @@ +package ccipdata + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + "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/logger" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +type LeafHasherInterface[H hashlib.Hash] interface { + HashLeaf(log types.Log) (H, error) +} + +const ( + COMMIT_CCIP_SENDS = "Commit ccip sends" +) + +//go:generate mockery --quiet --name OnRampReader --output . --filename onramp_reader_mock.go --inpackage --case=underscore +type OnRampReader interface { + Closer + // GetSendRequestsGteSeqNum returns all the message send requests with sequence number greater than or equal to the provided. + // If checkFinalityTags is set to true then confs param is ignored, the latest finalized block is used in the query. + GetSendRequestsGteSeqNum(ctx context.Context, seqNum uint64, confs int) ([]Event[internal.EVM2EVMMessage], error) + // GetSendRequestsBetweenSeqNums returns all the message send requests in the provided sequence numbers range (inclusive). + GetSendRequestsBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, confs int) ([]Event[internal.EVM2EVMMessage], error) + // Get router configured in the onRamp + RouterAddress() (common.Address, error) +} + +// NewOnRampReader determines the appropriate version of the onramp and returns a reader for it +func NewOnRampReader(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client, finalityTags bool, qopts ...pg.QOpt) (OnRampReader, error) { + contractType, version, err := ccipconfig.TypeAndVersion(onRampAddress, source) + if err != nil { + return nil, errors.Errorf("expected %v got %v", ccipconfig.EVM2EVMOnRamp, contractType) + } + switch version.String() { + case v1_0_0: + return NewOnRampV1_0_0(lggr, sourceSelector, destSelector, onRampAddress, sourceLP, source, finalityTags) + case v1_1_0: + return NewOnRampV1_1_0(lggr, sourceSelector, destSelector, onRampAddress, sourceLP, source, finalityTags) + case v1_2_0: + return NewOnRampV1_2_0(lggr, sourceSelector, destSelector, onRampAddress, sourceLP, source, finalityTags) + default: + return nil, errors.Errorf("got unexpected version %v", version.String()) + } +} + +func latestFinalizedBlockHash(ctx context.Context, client client.Client) (common.Hash, error) { + // If the chain is based on explicit finality we only examine logs less than or equal to the latest finalized block number. + // NOTE: there appears to be a bug in ethclient whereby BlockByNumber fails with "unsupported txtype" when trying to parse the block + // when querying L2s, headers however work. + // TODO (CCIP-778): Migrate to core finalized tags, below doesn't work for some chains e.g. Celo. + latestFinalizedHeader, err := client.HeaderByNumber( + ctx, + big.NewInt(rpc.FinalizedBlockNumber.Int64()), + ) + if err != nil { + return common.Hash{}, err + } + + if latestFinalizedHeader == nil { + return common.Hash{}, errors.New("latest finalized header is nil") + } + if latestFinalizedHeader.Number == nil { + return common.Hash{}, errors.New("latest finalized number is nil") + } + return latestFinalizedHeader.Hash(), nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_mock.go new file mode 100644 index 0000000000..7ff71a50b4 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_reader_mock.go @@ -0,0 +1,132 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package ccipdata + +import ( + context "context" + + common "github.com/ethereum/go-ethereum/common" + + internal "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + mock "github.com/stretchr/testify/mock" + + pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +// MockOnRampReader is an autogenerated mock type for the OnRampReader type +type MockOnRampReader struct { + mock.Mock +} + +// Close provides a mock function with given fields: qopts +func (_m *MockOnRampReader) Close(qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 error + if rf, ok := ret.Get(0).(func(...pg.QOpt) error); ok { + r0 = rf(qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetSendRequestsBetweenSeqNums provides a mock function with given fields: ctx, seqNumMin, seqNumMax, confs +func (_m *MockOnRampReader) GetSendRequestsBetweenSeqNums(ctx context.Context, seqNumMin uint64, seqNumMax uint64, confs int) ([]Event[internal.EVM2EVMMessage], error) { + ret := _m.Called(ctx, seqNumMin, seqNumMax, confs) + + var r0 []Event[internal.EVM2EVMMessage] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, int) ([]Event[internal.EVM2EVMMessage], error)); ok { + return rf(ctx, seqNumMin, seqNumMax, confs) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, int) []Event[internal.EVM2EVMMessage]); ok { + r0 = rf(ctx, seqNumMin, seqNumMax, confs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]Event[internal.EVM2EVMMessage]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, uint64, int) error); ok { + r1 = rf(ctx, seqNumMin, seqNumMax, confs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetSendRequestsGteSeqNum provides a mock function with given fields: ctx, seqNum, confs +func (_m *MockOnRampReader) GetSendRequestsGteSeqNum(ctx context.Context, seqNum uint64, confs int) ([]Event[internal.EVM2EVMMessage], error) { + ret := _m.Called(ctx, seqNum, confs) + + var r0 []Event[internal.EVM2EVMMessage] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, int) ([]Event[internal.EVM2EVMMessage], error)); ok { + return rf(ctx, seqNum, confs) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, int) []Event[internal.EVM2EVMMessage]); ok { + r0 = rf(ctx, seqNum, confs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]Event[internal.EVM2EVMMessage]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, int) error); ok { + r1 = rf(ctx, seqNum, confs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RouterAddress provides a mock function with given fields: +func (_m *MockOnRampReader) RouterAddress() (common.Address, error) { + ret := _m.Called() + + var r0 common.Address + var r1 error + if rf, ok := ret.Get(0).(func() (common.Address, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +type mockConstructorTestingTNewMockOnRampReader interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockOnRampReader creates a new instance of MockOnRampReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockOnRampReader(t mockConstructorTestingTNewMockOnRampReader) *MockOnRampReader { + mock := &MockOnRampReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0.go new file mode 100644 index 0000000000..55c0edbc0b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0.go @@ -0,0 +1,238 @@ +package ccipdata + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/math" + "github.com/ethereum/go-ethereum/core/types" + "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/ccip/generated/evm_2_evm_onramp_1_0_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +const ( + CCIPSendRequestedEventNameV1_0_0 = "CCIPSendRequested" + MetaDataHashPrefixV1_0_0 = "EVM2EVMMessageEvent" +) + +var leafDomainSeparator = [1]byte{0x00} + +type LeafHasherV1_0_0 struct { + metaDataHash [32]byte + ctx hashlib.Ctx[[32]byte] + onRamp *evm_2_evm_onramp_1_0_0.EVM2EVMOnRamp +} + +func getMetaDataHash[H hashlib.Hash](ctx hashlib.Ctx[H], prefix [32]byte, sourceChainSelector uint64, onRampId common.Address, destChainSelector uint64) H { + paddedOnRamp := onRampId.Hash() + return ctx.Hash(utils.ConcatBytes(prefix[:], math.U256Bytes(big.NewInt(0).SetUint64(sourceChainSelector)), math.U256Bytes(big.NewInt(0).SetUint64(destChainSelector)), paddedOnRamp[:])) +} + +func NewLeafHasherV1_0_0(sourceChainSelector uint64, destChainSelector uint64, onRampId common.Address, ctx hashlib.Ctx[[32]byte], onRamp *evm_2_evm_onramp_1_0_0.EVM2EVMOnRamp) *LeafHasherV1_0_0 { + return &LeafHasherV1_0_0{ + metaDataHash: getMetaDataHash(ctx, ctx.Hash([]byte(MetaDataHashPrefixV1_0_0)), sourceChainSelector, onRampId, destChainSelector), + ctx: ctx, + onRamp: onRamp, + } +} + +func (t *LeafHasherV1_0_0) HashLeaf(log types.Log) ([32]byte, error) { + message, err := t.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return [32]byte{}, err + } + encodedTokens, err := utils.ABIEncode( + `[ +{"components": [{"name":"token","type":"address"},{"name":"amount","type":"uint256"}], "type":"tuple[]"}]`, message.Message.TokenAmounts) + if err != nil { + return [32]byte{}, err + } + + packedValues, err := utils.ABIEncode( + `[ +{"name": "leafDomainSeparator","type":"bytes1"}, +{"name": "metadataHash", "type":"bytes32"}, +{"name": "sequenceNumber", "type":"uint64"}, +{"name": "nonce", "type":"uint64"}, +{"name": "sender", "type":"address"}, +{"name": "receiver", "type":"address"}, +{"name": "dataHash", "type":"bytes32"}, +{"name": "tokenAmountsHash", "type":"bytes32"}, +{"name": "gasLimit", "type":"uint256"}, +{"name": "strict", "type":"bool"}, +{"name": "feeToken","type": "address"}, +{"name": "feeTokenAmount","type": "uint256"} +]`, + leafDomainSeparator, + t.metaDataHash, + message.Message.SequenceNumber, + message.Message.Nonce, + message.Message.Sender, + message.Message.Receiver, + t.ctx.Hash(message.Message.Data), + t.ctx.Hash(encodedTokens), + message.Message.GasLimit, + message.Message.Strict, + message.Message.FeeToken, + message.Message.FeeTokenAmount, + ) + if err != nil { + return [32]byte{}, err + } + return t.ctx.Hash(packedValues), nil +} + +var _ OnRampReader = &OnRampV1_0_0{} + +type OnRampV1_0_0 struct { + address common.Address + onRamp *evm_2_evm_onramp_1_0_0.EVM2EVMOnRamp + finalityTags bool + lp logpoller.LogPoller + lggr logger.Logger + client client.Client + leafHasher LeafHasherInterface[[32]byte] + filterName string + sendRequestedEventSig common.Hash + sendRequestedSeqNumberWord int +} + +func (o *OnRampV1_0_0) GetLastUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, txHash common.Hash) ([]byte, error) { + return nil, errors.New("USDC not supported in < 1.2.0") +} + +func NewOnRampV1_0_0(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client, finalityTags bool) (*OnRampV1_0_0, error) { + onRamp, err := evm_2_evm_onramp_1_0_0.NewEVM2EVMOnRamp(onRampAddress, source) + if err != nil { + return nil, err + } + onRampABI := abihelpers.MustParseABI(evm_2_evm_onramp_1_0_0.EVM2EVMOnRampABI) + // Subscribe to the relevant logs + name := logpoller.FilterName(COMMIT_CCIP_SENDS, onRampAddress) + eventSig := abihelpers.MustGetEventID(CCIPSendRequestedEventNameV1_0_0, onRampABI) + err = sourceLP.RegisterFilter(logpoller.Filter{ + Name: name, + EventSigs: []common.Hash{eventSig}, + Addresses: []common.Address{onRampAddress}, + }) + if err != nil { + return nil, err + } + return &OnRampV1_0_0{ + lggr: lggr, + address: onRampAddress, + onRamp: onRamp, + lp: sourceLP, + finalityTags: finalityTags, + leafHasher: NewLeafHasherV1_0_0(sourceSelector, destSelector, onRampAddress, hashlib.NewKeccakCtx(), onRamp), + filterName: name, + // offset || sourceChainID || seqNum || ... + sendRequestedSeqNumberWord: 2, + sendRequestedEventSig: eventSig, + }, nil +} + +func (o *OnRampV1_0_0) logToMessage(log types.Log) (*internal.EVM2EVMMessage, error) { + msg, err := o.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return nil, err + } + h, err := o.leafHasher.HashLeaf(log) + if err != nil { + return nil, err + } + tokensAndAmounts := make([]internal.TokenAmount, len(msg.Message.TokenAmounts)) + for i, tokenAndAmount := range msg.Message.TokenAmounts { + tokensAndAmounts[i] = internal.TokenAmount{ + Token: tokenAndAmount.Token, + Amount: tokenAndAmount.Amount, + } + } + return &internal.EVM2EVMMessage{ + SequenceNumber: msg.Message.SequenceNumber, + GasLimit: msg.Message.GasLimit, + Nonce: msg.Message.Nonce, + MessageId: msg.Message.MessageId, + SourceChainSelector: msg.Message.SourceChainSelector, + Sender: msg.Message.Sender, + Receiver: msg.Message.Receiver, + Strict: msg.Message.Strict, + FeeToken: msg.Message.FeeToken, + FeeTokenAmount: msg.Message.FeeTokenAmount, + Data: msg.Message.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: make([][]byte, len(msg.Message.TokenAmounts)), // Always empty in 1.0 + Hash: h, + }, nil +} + +func (o *OnRampV1_0_0) GetSendRequestsGteSeqNum(ctx context.Context, seqNum uint64, confs int) ([]Event[internal.EVM2EVMMessage], error) { + if !o.finalityTags { + logs, err2 := o.lp.LogsDataWordGreaterThan( + o.sendRequestedEventSig, + o.address, + o.sendRequestedSeqNumberWord, + abihelpers.EvmWord(seqNum), + confs, + pg.WithParentCtx(ctx), + ) + if err2 != nil { + return nil, fmt.Errorf("logs data word greater than: %w", err2) + } + return parseLogs[internal.EVM2EVMMessage](logs, o.lggr, o.logToMessage) + } + latestFinalizedHash, err := latestFinalizedBlockHash(ctx, o.client) + if err != nil { + return nil, err + } + logs, err := o.lp.LogsUntilBlockHashDataWordGreaterThan( + o.sendRequestedEventSig, + o.address, + o.sendRequestedSeqNumberWord, + abihelpers.EvmWord(seqNum), + latestFinalizedHash, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, fmt.Errorf("logs until block hash data word greater than: %w", err) + } + return parseLogs[internal.EVM2EVMMessage](logs, o.lggr, o.logToMessage) +} + +func (o *OnRampV1_0_0) RouterAddress() (common.Address, error) { + config, err := o.onRamp.GetDynamicConfig(nil) + if err != nil { + return common.Address{}, err + } + return config.Router, nil +} + +func (o *OnRampV1_0_0) GetSendRequestsBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, confs int) ([]Event[internal.EVM2EVMMessage], error) { + logs, err := o.lp.LogsDataWordRange( + o.sendRequestedEventSig, + o.address, + o.sendRequestedSeqNumberWord, + logpoller.EvmWord(seqNumMin), + logpoller.EvmWord(seqNumMax), + confs, + pg.WithParentCtx(ctx)) + if err != nil { + return nil, err + } + return parseLogs[internal.EVM2EVMMessage](logs, o.lggr, o.logToMessage) +} + +func (o *OnRampV1_0_0) Close(qopts ...pg.QOpt) error { + return o.lp.UnregisterFilter(o.filterName, qopts...) +} diff --git a/core/services/ocr2/plugins/ccip/internal/hashlib/leaf_hasher_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go similarity index 54% rename from core/services/ocr2/plugins/ccip/internal/hashlib/leaf_hasher_test.go rename to core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go index e2e0978f74..164e9bd617 100644 --- a/core/services/ocr2/plugins/ccip/internal/hashlib/leaf_hasher_test.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_0_0_test.go @@ -1,27 +1,33 @@ -package hashlib +package ccipdata import ( "encoding/hex" "math/big" + "strings" "testing" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp_1_0_0" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" ) -func TestHasher(t *testing.T) { +func TestHasherV1_0_0(t *testing.T) { sourceChainSelector, destChainSelector := uint64(1), uint64(4) onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") + onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp_1_0_0.EVM2EVMOnRampABI)) + require.NoError(t, err) - hashingCtx := NewKeccakCtx() - - hasher := NewLeafHasher(sourceChainSelector, destChainSelector, onRampAddress, hashingCtx) + ramp, err := evm_2_evm_onramp_1_0_0.NewEVM2EVMOnRamp(onRampAddress, nil) + require.NoError(t, err) + hashingCtx := hashlib.NewKeccakCtx() + hasher := NewLeafHasherV1_0_0(sourceChainSelector, destChainSelector, onRampAddress, hashingCtx, ramp) - message := evm_2_evm_onramp.InternalEVM2EVMMessage{ + message := evm_2_evm_onramp_1_0_0.InternalEVM2EVMMessage{ SourceChainSelector: sourceChainSelector, Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), @@ -32,20 +38,19 @@ func TestHasher(t *testing.T) { FeeToken: common.Address{}, FeeTokenAmount: big.NewInt(1), Data: []byte{}, - TokenAmounts: []evm_2_evm_onramp.ClientEVMTokenAmount{{Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}}, - SourceTokenData: [][]byte{}, + TokenAmounts: []evm_2_evm_onramp_1_0_0.ClientEVMTokenAmount{{Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}}, MessageId: [32]byte{}, } - pack, err := abihelpers.MessageArgs.Pack(message) + data, err := onRampABI.Events[CCIPSendRequestedEventNameV1_0_0].Inputs.Pack(message) require.NoError(t, err) - hash, err := hasher.HashLeaf(types.Log{Topics: []common.Hash{abihelpers.EventSignatures.SendRequested}, Data: pack}) + hash, err := hasher.HashLeaf(types.Log{Topics: []common.Hash{abihelpers.MustGetEventID("CCIPSendRequested", onRampABI)}, Data: data}) require.NoError(t, err) // NOTE: Must match spec - require.Equal(t, "46ad031bfb052db2e4a2514fed8dc480b98e5ce4acb55d5640d91407e0d8a3e9", hex.EncodeToString(hash[:])) + require.Equal(t, "26f282c6ac8231933b1799648d01ff6cec792a33fb37408b4d135968f9168ace", hex.EncodeToString(hash[:])) - message = evm_2_evm_onramp.InternalEVM2EVMMessage{ + message = evm_2_evm_onramp_1_0_0.InternalEVM2EVMMessage{ SourceChainSelector: sourceChainSelector, Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), @@ -56,27 +61,26 @@ func TestHasher(t *testing.T) { FeeToken: common.Address{}, FeeTokenAmount: big.NewInt(1e12), Data: []byte("foo bar baz"), - TokenAmounts: []evm_2_evm_onramp.ClientEVMTokenAmount{ + TokenAmounts: []evm_2_evm_onramp_1_0_0.ClientEVMTokenAmount{ {Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}, {Token: common.HexToAddress("0x6660000000000000000000000000000000000001"), Amount: big.NewInt(4204242)}, }, - SourceTokenData: [][]byte{{0x2, 0x1}}, - MessageId: [32]byte{}, + MessageId: [32]byte{}, } - pack, err = abihelpers.MessageArgs.Pack(message) + data, err = onRampABI.Events[CCIPSendRequestedEventNameV1_0_0].Inputs.Pack(message) require.NoError(t, err) - hash, err = hasher.HashLeaf(types.Log{Topics: []common.Hash{abihelpers.EventSignatures.SendRequested}, Data: pack}) + hash, err = hasher.HashLeaf(types.Log{Topics: []common.Hash{abihelpers.MustGetEventID("CCIPSendRequested", onRampABI)}, Data: data}) require.NoError(t, err) // NOTE: Must match spec - require.Equal(t, "4362a13a42e52ff5ce4324e7184dc7aa41704c3146bc842d35d95b94b32a78b6", hex.EncodeToString(hash[:])) + require.Equal(t, "05cee92e7cb86a37b6536554828a5b21ff20ac3d4ef821ec47056f1d963313de", hex.EncodeToString(hash[:])) } func TestMetaDataHash(t *testing.T) { sourceChainSelector, destChainSelector := uint64(1), uint64(4) onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") - ctx := NewKeccakCtx() - hash := GetMetaDataHash(ctx, ctx.Hash([]byte("EVM2EVMSubscriptionMessagePlus")), sourceChainSelector, onRampAddress, destChainSelector) - require.Equal(t, "e8b93c9d01a7a72ec6c7235e238701cf1511b267a31fdb78dd342649ee58c08d", hex.EncodeToString(hash[:])) + ctx := hashlib.NewKeccakCtx() + hash := getMetaDataHash(ctx, ctx.Hash([]byte(MetaDataHashPrefixV1_0_0)), sourceChainSelector, onRampAddress, destChainSelector) + require.Equal(t, "1409948abde219f43870c3d6d1c16beabd8878eb5039a3fa765eb56e4b8ded9e", hex.EncodeToString(hash[:])) } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_1_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_1_0.go new file mode 100644 index 0000000000..9695e90d0a --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_1_0.go @@ -0,0 +1,41 @@ +package ccipdata + +import ( + "github.com/ethereum/go-ethereum/common" + + "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/ccip/generated/evm_2_evm_onramp_1_1_0" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +var _ OnRampReader = &OnRampV1_1_0{} + +// OnRampV1_1_0 The only difference that the plugins care about in 1.1 is that the dynamic config struct has changed. +type OnRampV1_1_0 struct { + *OnRampV1_0_0 + onRamp *evm_2_evm_onramp_1_1_0.EVM2EVMOnRamp +} + +func NewOnRampV1_1_0(lggr logger.Logger, sourceSelector, destSelector uint64, onRampAddress common.Address, sourceLP logpoller.LogPoller, source client.Client, finalityTags bool) (*OnRampV1_1_0, error) { + onRamp, err := evm_2_evm_onramp_1_1_0.NewEVM2EVMOnRamp(onRampAddress, source) + if err != nil { + return nil, err + } + onRamp100, err := NewOnRampV1_0_0(lggr, sourceSelector, destSelector, onRampAddress, sourceLP, source, finalityTags) + if err != nil { + return nil, err + } + return &OnRampV1_1_0{ + OnRampV1_0_0: onRamp100, + onRamp: onRamp, + }, nil +} + +func (o *OnRampV1_1_0) RouterAddress() (common.Address, error) { + config, err := o.onRamp.GetDynamicConfig(nil) + if err != nil { + return common.Address{}, err + } + return config.Router, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0.go new file mode 100644 index 0000000000..5cc16aa905 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0.go @@ -0,0 +1,341 @@ +package ccipdata + +import ( + "context" + "fmt" + "math/big" + "strings" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/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/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +var ( + // Backwards compat for integration tests + CCIPSendRequestEventSigV1_2_0 common.Hash +) + +const ( + CCIPSendRequestSeqNumIndexV1_2_0 = 4 + CCIPSendRequestedEventNameV1_2_0 = "CCIPSendRequested" + EVM2EVMOffRampEventNameV1_2_0 = "EVM2EVMMessage" + MetaDataHashPrefixV1_2_0 = "EVM2EVMMessageHashV2" +) + +func init() { + onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp.EVM2EVMOnRampABI)) + if err != nil { + panic(err) + } + CCIPSendRequestEventSigV1_2_0 = abihelpers.MustGetEventID(CCIPSendRequestedEventNameV1_2_0, onRampABI) +} + +// Backwards compat for integration tests +func DecodeOffRampMessageV1_2_0(b []byte) (*evm_2_evm_offramp.InternalEVM2EVMMessage, error) { + offRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_offramp.EVM2EVMOffRampABI)) + if err != nil { + panic(err) + } + event, ok := offRampABI.Events[EVM2EVMOffRampEventNameV1_2_0] + if !ok { + panic("no such event") + } + unpacked, err := event.Inputs.Unpack(b) + if err != nil { + return nil, err + } + if len(unpacked) == 0 { + return nil, fmt.Errorf("no message found when unpacking") + } + + // Note must use unnamed type here + receivedCp, ok := unpacked[0].(struct { + SourceChainSelector uint64 `json:"sourceChainSelector"` + Sender common.Address `json:"sender"` + Receiver common.Address `json:"receiver"` + SequenceNumber uint64 `json:"sequenceNumber"` + GasLimit *big.Int `json:"gasLimit"` + Strict bool `json:"strict"` + Nonce uint64 `json:"nonce"` + FeeToken common.Address `json:"feeToken"` + FeeTokenAmount *big.Int `json:"feeTokenAmount"` + Data []uint8 `json:"data"` + TokenAmounts []struct { + Token common.Address `json:"token"` + Amount *big.Int `json:"amount"` + } `json:"tokenAmounts"` + SourceTokenData [][]byte `json:"sourceTokenData"` + MessageId [32]byte `json:"messageId"` + }) + if !ok { + return nil, fmt.Errorf("invalid format have %T want %T", unpacked[0], receivedCp) + } + var tokensAndAmounts []evm_2_evm_offramp.ClientEVMTokenAmount + for _, tokenAndAmount := range receivedCp.TokenAmounts { + tokensAndAmounts = append(tokensAndAmounts, evm_2_evm_offramp.ClientEVMTokenAmount{ + Token: tokenAndAmount.Token, + Amount: tokenAndAmount.Amount, + }) + } + + return &evm_2_evm_offramp.InternalEVM2EVMMessage{ + SourceChainSelector: receivedCp.SourceChainSelector, + Sender: receivedCp.Sender, + Receiver: receivedCp.Receiver, + SequenceNumber: receivedCp.SequenceNumber, + GasLimit: receivedCp.GasLimit, + Strict: receivedCp.Strict, + Nonce: receivedCp.Nonce, + FeeToken: receivedCp.FeeToken, + FeeTokenAmount: receivedCp.FeeTokenAmount, + Data: receivedCp.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: receivedCp.SourceTokenData, + MessageId: receivedCp.MessageId, + }, nil +} + +type LeafHasherV1_2_0 struct { + metaDataHash [32]byte + ctx hashlib.Ctx[[32]byte] + onRamp *evm_2_evm_onramp.EVM2EVMOnRamp +} + +func NewLeafHasherV1_2_0(sourceChainSelector uint64, destChainSelector uint64, onRampId common.Address, ctx hashlib.Ctx[[32]byte], onRamp *evm_2_evm_onramp.EVM2EVMOnRamp) *LeafHasherV1_2_0 { + return &LeafHasherV1_2_0{ + metaDataHash: getMetaDataHash(ctx, ctx.Hash([]byte(MetaDataHashPrefixV1_2_0)), sourceChainSelector, onRampId, destChainSelector), + ctx: ctx, + onRamp: onRamp, + } +} + +func (t *LeafHasherV1_2_0) HashLeaf(log types.Log) ([32]byte, error) { + msg, err := t.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return [32]byte{}, err + } + message := msg.Message + encodedTokens, err := utils.ABIEncode( + `[ +{"components": [{"name":"token","type":"address"},{"name":"amount","type":"uint256"}], "type":"tuple[]"}]`, message.TokenAmounts) + if err != nil { + return [32]byte{}, err + } + + bytesArray, err := abi.NewType("bytes[]", "bytes[]", nil) + if err != nil { + return [32]byte{}, err + } + + encodedSourceTokenData, err := abi.Arguments{abi.Argument{Type: bytesArray}}.PackValues([]interface{}{message.SourceTokenData}) + if err != nil { + return [32]byte{}, err + } + + packedFixedSizeValues, err := utils.ABIEncode( + `[ +{"name": "sender", "type":"address"}, +{"name": "receiver", "type":"address"}, +{"name": "sequenceNumber", "type":"uint64"}, +{"name": "gasLimit", "type":"uint256"}, +{"name": "strict", "type":"bool"}, +{"name": "nonce", "type":"uint64"}, +{"name": "feeToken","type": "address"}, +{"name": "feeTokenAmount","type": "uint256"} +]`, + message.Sender, + message.Receiver, + message.SequenceNumber, + message.GasLimit, + message.Strict, + message.Nonce, + message.FeeToken, + message.FeeTokenAmount, + ) + if err != nil { + return [32]byte{}, err + } + fixedSizeValuesHash := t.ctx.Hash(packedFixedSizeValues) + + packedValues, err := utils.ABIEncode( + `[ +{"name": "leafDomainSeparator","type":"bytes1"}, +{"name": "metadataHash", "type":"bytes32"}, +{"name": "fixedSizeValuesHash", "type":"bytes32"}, +{"name": "dataHash", "type":"bytes32"}, +{"name": "tokenAmountsHash", "type":"bytes32"}, +{"name": "sourceTokenDataHash", "type":"bytes32"} +]`, + leafDomainSeparator, + t.metaDataHash, + fixedSizeValuesHash, + t.ctx.Hash(message.Data), + t.ctx.Hash(encodedTokens), + t.ctx.Hash(encodedSourceTokenData), + ) + if err != nil { + return [32]byte{}, err + } + return t.ctx.Hash(packedValues), nil +} + +var _ OnRampReader = &OnRampV1_2_0{} + +// Significant change in 1.2: +// - CCIPSendRequested event signature has changed +type OnRampV1_2_0 struct { + onRamp *evm_2_evm_onramp.EVM2EVMOnRamp + address common.Address + lggr logger.Logger + lp logpoller.LogPoller + leafHasher LeafHasherInterface[[32]byte] + client client.Client + finalityTags bool + filterName string + sendRequestedEventSig common.Hash + sendRequestedSeqNumberWord int +} + +func (o *OnRampV1_2_0) logToMessage(log types.Log) (*internal.EVM2EVMMessage, error) { + msg, err := o.onRamp.ParseCCIPSendRequested(log) + if err != nil { + return nil, err + } + h, err := o.leafHasher.HashLeaf(log) + if err != nil { + return nil, err + } + tokensAndAmounts := make([]internal.TokenAmount, len(msg.Message.TokenAmounts)) + for i, tokenAndAmount := range msg.Message.TokenAmounts { + tokensAndAmounts[i] = internal.TokenAmount{ + Token: tokenAndAmount.Token, + Amount: tokenAndAmount.Amount, + } + } + + return &internal.EVM2EVMMessage{ + SequenceNumber: msg.Message.SequenceNumber, + GasLimit: msg.Message.GasLimit, + Nonce: msg.Message.Nonce, + MessageId: msg.Message.MessageId, + SourceChainSelector: msg.Message.SourceChainSelector, + Sender: msg.Message.Sender, + Receiver: msg.Message.Receiver, + Strict: msg.Message.Strict, + FeeToken: msg.Message.FeeToken, + FeeTokenAmount: msg.Message.FeeTokenAmount, + Data: msg.Message.Data, + TokenAmounts: tokensAndAmounts, + SourceTokenData: msg.Message.SourceTokenData, // Breaking change 1.2 + Hash: h, + }, nil +} + +func (o *OnRampV1_2_0) GetSendRequestsGteSeqNum(ctx context.Context, seqNum uint64, confs int) ([]Event[internal.EVM2EVMMessage], error) { + if !o.finalityTags { + logs, err2 := o.lp.LogsDataWordGreaterThan( + o.sendRequestedEventSig, + o.address, + o.sendRequestedSeqNumberWord, + abihelpers.EvmWord(seqNum), + confs, + pg.WithParentCtx(ctx), + ) + if err2 != nil { + return nil, fmt.Errorf("logs data word greater than: %w", err2) + } + return parseLogs[internal.EVM2EVMMessage](logs, o.lggr, o.logToMessage) + } + latestFinalizedHash, err := latestFinalizedBlockHash(ctx, o.client) + if err != nil { + return nil, err + } + logs, err := o.lp.LogsUntilBlockHashDataWordGreaterThan( + o.sendRequestedEventSig, + o.address, + o.sendRequestedSeqNumberWord, + abihelpers.EvmWord(seqNum), + latestFinalizedHash, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, fmt.Errorf("logs until block hash data word greater than: %w", err) + } + return parseLogs[internal.EVM2EVMMessage](logs, o.lggr, o.logToMessage) +} + +func (o *OnRampV1_2_0) GetSendRequestsBetweenSeqNums(ctx context.Context, seqNumMin, seqNumMax uint64, confs int) ([]Event[internal.EVM2EVMMessage], error) { + logs, err := o.lp.LogsDataWordRange( + o.sendRequestedEventSig, + o.address, + o.sendRequestedSeqNumberWord, + logpoller.EvmWord(seqNumMin), + logpoller.EvmWord(seqNumMax), + confs, + pg.WithParentCtx(ctx)) + if err != nil { + return nil, err + } + return parseLogs[internal.EVM2EVMMessage](logs, o.lggr, o.logToMessage) +} + +func (o *OnRampV1_2_0) RouterAddress() (common.Address, error) { + config, err := o.onRamp.GetDynamicConfig(nil) + if err != nil { + return common.Address{}, err + } + return config.Router, nil +} + +func (o *OnRampV1_2_0) Close(qopts ...pg.QOpt) error { + return o.lp.UnregisterFilter(o.filterName, qopts...) +} + +func NewOnRampV1_2_0( + lggr logger.Logger, + sourceSelector, + destSelector uint64, + onRampAddress common.Address, + sourceLP logpoller.LogPoller, + source client.Client, + finalityTags bool, +) (*OnRampV1_2_0, error) { + onRamp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, source) + if err != nil { + return nil, err + } + // Subscribe to the relevant logs + // Note we can keep the same prefix across 1.0/1.1 and 1.2 because the onramp addresses will be different + name := logpoller.FilterName(COMMIT_CCIP_SENDS, onRampAddress) + if err = sourceLP.RegisterFilter(logpoller.Filter{ + Name: name, + EventSigs: []common.Hash{CCIPSendRequestEventSigV1_2_0}, + Addresses: []common.Address{onRampAddress}, + }); err != nil { + return nil, err + } + return &OnRampV1_2_0{ + finalityTags: finalityTags, + lggr: lggr, + client: source, + lp: sourceLP, + leafHasher: NewLeafHasherV1_2_0(sourceSelector, destSelector, onRampAddress, hashlib.NewKeccakCtx(), onRamp), + onRamp: onRamp, + filterName: name, + address: onRampAddress, + sendRequestedSeqNumberWord: CCIPSendRequestSeqNumIndexV1_2_0, + sendRequestedEventSig: CCIPSendRequestEventSigV1_2_0, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go new file mode 100644 index 0000000000..d271b87654 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/onramp_v1_2_0_test.go @@ -0,0 +1,147 @@ +package ccipdata + +import ( + "context" + "encoding/hex" + "math/big" + "strings" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + 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/chains/evm/logpoller/mocks" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestHasherV1_2_0(t *testing.T) { + sourceChainSelector, destChainSelector := uint64(1), uint64(4) + onRampAddress := common.HexToAddress("0x5550000000000000000000000000000000000001") + onRampABI, err := abi.JSON(strings.NewReader(evm_2_evm_onramp.EVM2EVMOnRampABI)) + require.NoError(t, err) + + hashingCtx := hashlib.NewKeccakCtx() + ramp, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(onRampAddress, nil) + require.NoError(t, err) + hasher := NewLeafHasherV1_2_0(sourceChainSelector, destChainSelector, onRampAddress, hashingCtx, ramp) + + message := evm_2_evm_onramp.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1), + Data: []byte{}, + TokenAmounts: []evm_2_evm_onramp.ClientEVMTokenAmount{{Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}}, + SourceTokenData: [][]byte{}, + MessageId: [32]byte{}, + } + + data, err := onRampABI.Events[CCIPSendRequestedEventNameV1_2_0].Inputs.Pack(message) + require.NoError(t, err) + hash, err := hasher.HashLeaf(types.Log{Topics: []common.Hash{CCIPSendRequestEventSigV1_2_0}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "46ad031bfb052db2e4a2514fed8dc480b98e5ce4acb55d5640d91407e0d8a3e9", hex.EncodeToString(hash[:])) + + message = evm_2_evm_onramp.InternalEVM2EVMMessage{ + SourceChainSelector: sourceChainSelector, + Sender: common.HexToAddress("0x1110000000000000000000000000000000000001"), + Receiver: common.HexToAddress("0x2220000000000000000000000000000000000001"), + SequenceNumber: 1337, + GasLimit: big.NewInt(100), + Strict: false, + Nonce: 1337, + FeeToken: common.Address{}, + FeeTokenAmount: big.NewInt(1e12), + Data: []byte("foo bar baz"), + TokenAmounts: []evm_2_evm_onramp.ClientEVMTokenAmount{ + {Token: common.HexToAddress("0x4440000000000000000000000000000000000001"), Amount: big.NewInt(12345678900)}, + {Token: common.HexToAddress("0x6660000000000000000000000000000000000001"), Amount: big.NewInt(4204242)}, + }, + SourceTokenData: [][]byte{{0x2, 0x1}}, + MessageId: [32]byte{}, + } + + data, err = onRampABI.Events[CCIPSendRequestedEventNameV1_2_0].Inputs.Pack(message) + require.NoError(t, err) + hash, err = hasher.HashLeaf(types.Log{Topics: []common.Hash{CCIPSendRequestEventSigV1_2_0}, Data: data}) + require.NoError(t, err) + + // NOTE: Must match spec + require.Equal(t, "4362a13a42e52ff5ce4324e7184dc7aa41704c3146bc842d35d95b94b32a78b6", hex.EncodeToString(hash[:])) +} + +func TestLogPollerClient_GetSendRequestsGteSeqNum(t *testing.T) { + onRampAddr := utils.RandomAddress() + seqNum := uint64(100) + confs := 4 + lggr := logger.TestLogger(t) + t.Run("using confs", func(t *testing.T) { + lp := mocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + onRampV2, err := NewOnRampV1_2_0(lggr, 1, 1, onRampAddr, lp, nil, false) + require.NoError(t, err) + lp.On("LogsDataWordGreaterThan", + onRampV2.sendRequestedEventSig, + onRampAddr, + onRampV2.sendRequestedSeqNumberWord, + abihelpers.EvmWord(seqNum), + confs, + mock.Anything, + ).Return([]logpoller.Log{}, nil) + + //c := &LogPollerReader{lp: lp} + events, err := onRampV2.GetSendRequestsGteSeqNum( + context.Background(), + seqNum, + confs, + ) + assert.NoError(t, err) + assert.Empty(t, events) + lp.AssertExpectations(t) + }) + + t.Run("using latest confirmed block", func(t *testing.T) { + h := &types.Header{Number: big.NewInt(100000)} + cl := evmClientMocks.NewClient(t) + cl.On("HeaderByNumber", mock.Anything, mock.Anything).Return(h, nil) + lp := mocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + onRampV2, err := NewOnRampV1_2_0(lggr, 1, 1, onRampAddr, lp, cl, true) + require.NoError(t, err) + lp.On("LogsUntilBlockHashDataWordGreaterThan", + onRampV2.sendRequestedEventSig, + onRampAddr, + onRampV2.sendRequestedSeqNumberWord, + abihelpers.EvmWord(seqNum), + h.Hash(), + mock.Anything, + ).Return([]logpoller.Log{}, nil) + + events, err := onRampV2.GetSendRequestsGteSeqNum( + context.Background(), + seqNum, + confs, + ) + assert.NoError(t, err) + assert.Empty(t, events) + lp.AssertExpectations(t) + cl.AssertExpectations(t) + }) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go new file mode 100644 index 0000000000..a8738a14fd --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader.go @@ -0,0 +1,79 @@ +package ccipdata + +import ( + "context" + "math/big" + "time" + + "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/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +const ( + COMMIT_PRICE_UPDATES = "Commit price updates" + FEE_TOKEN_ADDED = "Fee token added" + FEE_TOKEN_REMOVED = "Fee token removed" +) + +var ( + UsdPerUnitGasUpdatedV1_0_0 = abihelpers.MustGetEventID("UsdPerUnitGasUpdated", abihelpers.MustParseABI(price_registry.PriceRegistryABI)) +) + +type TokenPrice struct { + Token common.Address + Value *big.Int +} + +type TokenPriceUpdate struct { + TokenPrice + Timestamp *big.Int +} + +type GasPrice struct { + DestChainSelector uint64 + Value *big.Int +} + +type GasPriceUpdate struct { + GasPrice + Timestamp *big.Int +} + +//go:generate mockery --quiet --name PriceRegistryReader --output . --filename price_registry_reader_mock.go --inpackage --case=underscore +type PriceRegistryReader interface { + Close(qopts ...pg.QOpt) error + // GetTokenPriceUpdatesCreatedAfter returns all the token price updates that happened after the provided timestamp. + GetTokenPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confs int) ([]Event[TokenPriceUpdate], error) + // GetGasPriceUpdatesCreatedAfter returns all the gas price updates that happened after the provided timestamp. + GetGasPriceUpdatesCreatedAfter(ctx context.Context, chainSelector uint64, ts time.Time, confs int) ([]Event[GasPriceUpdate], error) + Address() common.Address + FeeTokenEvents() []common.Hash + GetFeeTokens(ctx context.Context) ([]common.Address, error) + GetTokenPrices(ctx context.Context, wantedTokens []common.Address) ([]TokenPriceUpdate, error) +} + +// NewPriceRegistryReader determines the appropriate version of the price registry and returns a reader for it. +func NewPriceRegistryReader(lggr logger.Logger, priceRegistryAddress common.Address, lp logpoller.LogPoller, cl client.Client) (PriceRegistryReader, error) { + _, version, err := ccipconfig.TypeAndVersion(priceRegistryAddress, cl) + if err != nil { + // TODO: would this always through a method not found? + // Unfortunately the v1 price registry doesn't have a method to get the version so assume if it errors + // its v1. + return NewPriceRegistryV1_0_0(lggr, priceRegistryAddress, lp, cl) + } + switch version.String() { + case v1_2_0: + // TODO: ABI is same now but will break shortly with multigas price updates + return NewPriceRegistryV1_0_0(lggr, priceRegistryAddress, lp, cl) + default: + return nil, errors.Errorf("got unexpected version %v", version.String()) + } +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_mock.go new file mode 100644 index 0000000000..2ebf23e211 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_mock.go @@ -0,0 +1,191 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package ccipdata + +import ( + context "context" + + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" + + time "time" +) + +// MockPriceRegistryReader is an autogenerated mock type for the PriceRegistryReader type +type MockPriceRegistryReader struct { + mock.Mock +} + +// Address provides a mock function with given fields: +func (_m *MockPriceRegistryReader) Address() common.Address { + ret := _m.Called() + + var r0 common.Address + if rf, ok := ret.Get(0).(func() common.Address); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Address) + } + } + + return r0 +} + +// Close provides a mock function with given fields: qopts +func (_m *MockPriceRegistryReader) Close(qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 error + if rf, ok := ret.Get(0).(func(...pg.QOpt) error); ok { + r0 = rf(qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// FeeTokenEvents provides a mock function with given fields: +func (_m *MockPriceRegistryReader) FeeTokenEvents() []common.Hash { + ret := _m.Called() + + var r0 []common.Hash + if rf, ok := ret.Get(0).(func() []common.Hash); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Hash) + } + } + + return r0 +} + +// GetFeeTokens provides a mock function with given fields: ctx +func (_m *MockPriceRegistryReader) GetFeeTokens(ctx context.Context) ([]common.Address, error) { + ret := _m.Called(ctx) + + var r0 []common.Address + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) ([]common.Address, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) []common.Address); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Address) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetGasPriceUpdatesCreatedAfter provides a mock function with given fields: ctx, chainSelector, ts, confs +func (_m *MockPriceRegistryReader) GetGasPriceUpdatesCreatedAfter(ctx context.Context, chainSelector uint64, ts time.Time, confs int) ([]Event[GasPriceUpdate], error) { + ret := _m.Called(ctx, chainSelector, ts, confs) + + var r0 []Event[GasPriceUpdate] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, time.Time, int) ([]Event[GasPriceUpdate], error)); ok { + return rf(ctx, chainSelector, ts, confs) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, time.Time, int) []Event[GasPriceUpdate]); ok { + r0 = rf(ctx, chainSelector, ts, confs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]Event[GasPriceUpdate]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, time.Time, int) error); ok { + r1 = rf(ctx, chainSelector, ts, confs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetTokenPriceUpdatesCreatedAfter provides a mock function with given fields: ctx, ts, confs +func (_m *MockPriceRegistryReader) GetTokenPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confs int) ([]Event[TokenPriceUpdate], error) { + ret := _m.Called(ctx, ts, confs) + + var r0 []Event[TokenPriceUpdate] + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) ([]Event[TokenPriceUpdate], error)); ok { + return rf(ctx, ts, confs) + } + if rf, ok := ret.Get(0).(func(context.Context, time.Time, int) []Event[TokenPriceUpdate]); ok { + r0 = rf(ctx, ts, confs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]Event[TokenPriceUpdate]) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, time.Time, int) error); ok { + r1 = rf(ctx, ts, confs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetTokenPrices provides a mock function with given fields: ctx, wantedTokens +func (_m *MockPriceRegistryReader) GetTokenPrices(ctx context.Context, wantedTokens []common.Address) ([]TokenPriceUpdate, error) { + ret := _m.Called(ctx, wantedTokens) + + var r0 []TokenPriceUpdate + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []common.Address) ([]TokenPriceUpdate, error)); ok { + return rf(ctx, wantedTokens) + } + if rf, ok := ret.Get(0).(func(context.Context, []common.Address) []TokenPriceUpdate); ok { + r0 = rf(ctx, wantedTokens) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]TokenPriceUpdate) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []common.Address) error); ok { + r1 = rf(ctx, wantedTokens) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +type mockConstructorTestingTNewMockPriceRegistryReader interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockPriceRegistryReader creates a new instance of MockPriceRegistryReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockPriceRegistryReader(t mockConstructorTestingTNewMockPriceRegistryReader) *MockPriceRegistryReader { + mock := &MockPriceRegistryReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go new file mode 100644 index 0000000000..2e3f73733b --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_reader_test.go @@ -0,0 +1,24 @@ +package ccipdata + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "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/logger" +) + +func TestPriceRegistryFilters(t *testing.T) { + cl := mocks.NewClient(t) + cl.On("ConfiguredChainID").Return(big.NewInt(1)) + + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { + c, err := NewPriceRegistryV1_0_0(logger.TestLogger(t), addr, lp, cl) + require.NoError(t, err) + return c + }, 3) +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go new file mode 100644 index 0000000000..d05f86fbff --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/price_registry_v1_0_0.go @@ -0,0 +1,174 @@ +package ccipdata + +import ( + "context" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/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/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/logpollerutil" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/observability" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +var ( + _ PriceRegistryReader = &PriceRegistryV1_0_0{} +) + +const ExecPluginLabel = "exec" + +type PriceRegistryV1_0_0 struct { + priceRegistry *observability.ObservedPriceRegistryV1_0_0 + address common.Address + lp logpoller.LogPoller + lggr logger.Logger + filters []logpoller.Filter + tokenUpdated common.Hash + gasUpdated common.Hash +} + +func (p *PriceRegistryV1_0_0) FeeTokenEvents() []common.Hash { + priceRegABI := abihelpers.MustParseABI(price_registry.PriceRegistryABI) + return []common.Hash{abihelpers.MustGetEventID("FeeTokenRemoved", priceRegABI), abihelpers.MustGetEventID("FeeTokenAdded", priceRegABI)} +} + +func (p *PriceRegistryV1_0_0) GetTokenPrices(ctx context.Context, wantedTokens []common.Address) ([]TokenPriceUpdate, error) { + tps, err := p.priceRegistry.GetTokenPrices(&bind.CallOpts{Context: ctx}, wantedTokens) + if err != nil { + return nil, err + } + var tpu []TokenPriceUpdate + for i, tp := range tps { + tpu = append(tpu, TokenPriceUpdate{ + TokenPrice: TokenPrice{ + Token: wantedTokens[i], + Value: tp.Value, + }, + Timestamp: big.NewInt(int64(tp.Timestamp)), // TODO: valid conversion + }) + } + return tpu, nil +} + +func (p *PriceRegistryV1_0_0) Address() common.Address { + return p.address +} + +func (p *PriceRegistryV1_0_0) GetFeeTokens(ctx context.Context) ([]common.Address, error) { + return p.priceRegistry.GetFeeTokens(&bind.CallOpts{Context: ctx}) +} + +func (p *PriceRegistryV1_0_0) Close(opts ...pg.QOpt) error { + return logpollerutil.UnregisterLpFilters(p.lp, p.filters, opts...) +} + +func (p *PriceRegistryV1_0_0) GetTokenPriceUpdatesCreatedAfter(ctx context.Context, ts time.Time, confs int) ([]Event[TokenPriceUpdate], error) { + logs, err := p.lp.LogsCreatedAfter( + p.tokenUpdated, + p.address, + ts, + confs, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, err + } + + return parseLogs[TokenPriceUpdate]( + logs, + p.lggr, + func(log types.Log) (*TokenPriceUpdate, error) { + tp, err := p.priceRegistry.ParseUsdPerTokenUpdated(log) + if err != nil { + return nil, err + } + return &TokenPriceUpdate{ + TokenPrice: TokenPrice{ + Token: tp.Token, + Value: tp.Value, + }, + Timestamp: tp.Timestamp, + }, nil + }, + ) +} + +func (p *PriceRegistryV1_0_0) GetGasPriceUpdatesCreatedAfter(ctx context.Context, chainSelector uint64, ts time.Time, confs int) ([]Event[GasPriceUpdate], error) { + logs, err := p.lp.IndexedLogsCreatedAfter( + p.gasUpdated, + p.address, + 1, + []common.Hash{abihelpers.EvmWord(chainSelector)}, + ts, + confs, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, err + } + + return parseLogs[GasPriceUpdate]( + logs, + p.lggr, + func(log types.Log) (*GasPriceUpdate, error) { + p, err := p.priceRegistry.ParseUsdPerUnitGasUpdated(log) + if err != nil { + return nil, err + } + return &GasPriceUpdate{ + GasPrice: GasPrice{ + DestChainSelector: p.DestChain, + Value: p.Value, + }, + Timestamp: p.Timestamp, + }, nil + }, + ) +} + +func NewPriceRegistryV1_0_0(lggr logger.Logger, priceRegistryAddr common.Address, lp logpoller.LogPoller, ec client.Client) (*PriceRegistryV1_0_0, error) { + // TODO pass label + priceRegistry, err := observability.NewObservedPriceRegistryV1_0_0(priceRegistryAddr, ExecPluginLabel, ec) + if err != nil { + return nil, err + } + priceRegistryABI := abihelpers.MustParseABI(price_registry.PriceRegistryABI) + // TODO: clean up strings + tokenUpdated := abihelpers.MustGetEventID("UsdPerTokenUpdated", priceRegistryABI) + var filters = []logpoller.Filter{{ + Name: logpoller.FilterName(COMMIT_PRICE_UPDATES, priceRegistryAddr.String()), + EventSigs: []common.Hash{UsdPerUnitGasUpdatedV1_0_0, tokenUpdated}, + Addresses: []common.Address{priceRegistryAddr}, + }, + { + Name: logpoller.FilterName(FEE_TOKEN_ADDED, priceRegistryAddr.String()), + EventSigs: []common.Hash{abihelpers.MustGetEventID("FeeTokenAdded", priceRegistryABI)}, + Addresses: []common.Address{priceRegistryAddr}, + }, + { + Name: logpoller.FilterName(FEE_TOKEN_REMOVED, priceRegistryAddr.String()), + EventSigs: []common.Hash{abihelpers.MustGetEventID("FeeTokenAdded", priceRegistryABI)}, + Addresses: []common.Address{priceRegistryAddr}, + }} + err = logpollerutil.RegisterLpFilters(lp, filters) + if err != nil { + return nil, err + } + return &PriceRegistryV1_0_0{ + priceRegistry: priceRegistry, + address: priceRegistryAddr, + lp: lp, + lggr: lggr, + gasUpdated: UsdPerUnitGasUpdatedV1_0_0, + tokenUpdated: tokenUpdated, + filters: filters, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go index ffae5ec7ca..48f2b2e71b 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader.go @@ -6,51 +6,35 @@ import ( "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) type Event[T any] struct { Data T - BlockMeta + Meta } -type BlockMeta struct { +type Meta struct { BlockTimestamp time.Time BlockNumber int64 + TxHash common.Hash + LogIndex uint +} + +const ( + v1_0_0 = "1.0.0" + v1_1_0 = "1.1.0" + v1_2_0 = "1.2.0" +) + +type Closer interface { + Close(qopts ...pg.QOpt) error } // Client can be used to fetch CCIP related parsed on-chain data. // -//go:generate mockery --quiet --name Reader --output . --filename mock.go --inpackage --case=underscore +//go:generate mockery --quiet --name Reader --output . --filename reader_mock.go --inpackage --case=underscore type Reader interface { - // GetSendRequestsGteSeqNum returns all the message send requests with sequence number greater than or equal to the provided. - // If checkFinalityTags is set to true then confs param is ignored, the latest finalized block is used in the query. - GetSendRequestsGteSeqNum(ctx context.Context, onRamp common.Address, seqNum uint64, checkFinalityTags bool, confs int) ([]Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], error) - - // GetSendRequestsBetweenSeqNums returns all the message send requests in the provided sequence numbers range (inclusive). - GetSendRequestsBetweenSeqNums(ctx context.Context, onRamp common.Address, seqNumMin, seqNumMax uint64, confs int) ([]Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], error) - - // GetTokenPriceUpdatesCreatedAfter returns all the token price updates that happened after the provided timestamp. - GetTokenPriceUpdatesCreatedAfter(ctx context.Context, priceRegistry common.Address, ts time.Time, confs int) ([]Event[price_registry.PriceRegistryUsdPerTokenUpdated], error) - - // GetGasPriceUpdatesCreatedAfter returns all the gas price updates that happened after the provided timestamp. - GetGasPriceUpdatesCreatedAfter(ctx context.Context, priceRegistry common.Address, chainSelector uint64, ts time.Time, confs int) ([]Event[price_registry.PriceRegistryUsdPerUnitGasUpdated], error) - - // GetExecutionStateChangesBetweenSeqNums returns all the execution state change events for the provided message sequence numbers (inclusive). - GetExecutionStateChangesBetweenSeqNums(ctx context.Context, offRamp common.Address, seqNumMin, seqNumMax uint64, confs int) ([]Event[evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged], error) - - // GetAcceptedCommitReportsGteSeqNum returns all the accepted commit reports that have sequence number greater than or equal to the provided. - GetAcceptedCommitReportsGteSeqNum(ctx context.Context, commitStoreAddress common.Address, seqNum uint64, confs int) ([]Event[commit_store.CommitStoreReportAccepted], error) - - // GetAcceptedCommitReportsGteTimestamp returns all the commit reports with timestamp greater than or equal to the provided. - GetAcceptedCommitReportsGteTimestamp(ctx context.Context, commitStoreAddress common.Address, ts time.Time, confs int) ([]Event[commit_store.CommitStoreReportAccepted], error) - - // GetLastUSDCMessagePriorToLogIndexInTx returns the last USDC message that was sent before the provided log index in the given transaction. - GetLastUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, txHash common.Hash) ([]byte, error) - // LatestBlock returns the latest known/parsed block of the underlying implementation. LatestBlock(ctx context.Context) (int64, error) } diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_mock.go new file mode 100644 index 0000000000..f6eca7f7b6 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/reader_mock.go @@ -0,0 +1,53 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package ccipdata + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" +) + +// MockReader is an autogenerated mock type for the Reader type +type MockReader struct { + mock.Mock +} + +// LatestBlock provides a mock function with given fields: ctx +func (_m *MockReader) LatestBlock(ctx context.Context) (int64, error) { + ret := _m.Called(ctx) + + var r0 int64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (int64, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) int64); ok { + r0 = rf(ctx) + } else { + r0 = ret.Get(0).(int64) + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +type mockConstructorTestingTNewMockReader interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockReader creates a new instance of MockReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockReader(t mockConstructorTestingTNewMockReader) *MockReader { + mock := &MockReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go new file mode 100644 index 0000000000..053cc3dce5 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader.go @@ -0,0 +1,97 @@ +package ccipdata + +import ( + "context" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/pkg/errors" + + "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/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +const ( + MESSAGE_SENT_FILTER_NAME = "USDC message sent" +) + +//go:generate mockery --quiet --name USDCReader --output . --filename usdc_reader_mock.go --inpackage --case=underscore +type USDCReader interface { + // GetLastUSDCMessagePriorToLogIndexInTx returns the last USDC message that was sent before the provided log index in the given transaction. + GetLastUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, txHash common.Hash) ([]byte, error) + Close(qopts ...pg.QOpt) error +} + +type USDCReaderImpl struct { + usdcMessageSent common.Hash + lp logpoller.LogPoller + filterName string + lggr logger.Logger +} + +func (u *USDCReaderImpl) Close(qopts ...pg.QOpt) error { + return u.lp.UnregisterFilter(u.filterName, qopts...) +} + +// usdcPayload has to match the onchain event emitted by the USDC message transmitter +type usdcPayload []byte + +func (d usdcPayload) AbiString() string { + return `[{"type": "bytes"}]` +} + +func (d usdcPayload) Validate() error { + if len(d) == 0 { + return errors.New("must be non-empty") + } + return nil +} + +func parseUSDCMessageSent(logData []byte) ([]byte, error) { + decodeAbiStruct, err := abihelpers.DecodeAbiStruct[usdcPayload](logData) + if err != nil { + return nil, err + } + return decodeAbiStruct, nil +} + +func (u *USDCReaderImpl) GetLastUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, txHash common.Hash) ([]byte, error) { + logs, err := u.lp.IndexedLogsByTxHash( + u.usdcMessageSent, + txHash, + pg.WithParentCtx(ctx), + ) + if err != nil { + return nil, err + } + + for i := range logs { + current := logs[len(logs)-i-1] + if current.LogIndex < logIndex { + u.lggr.Infow("Found USDC message", "logIndex", current.LogIndex, "txHash", current.TxHash.Hex(), "data", hexutil.Encode(current.Data)) + return parseUSDCMessageSent(current.Data) + } + } + return nil, errors.Errorf("no USDC message found prior to log index %d in tx %s", logIndex, txHash.Hex()) +} + +func NewUSDCReader(lggr logger.Logger, transmitter common.Address, lp logpoller.LogPoller) (*USDCReaderImpl, error) { + filterName := logpoller.FilterName(MESSAGE_SENT_FILTER_NAME, transmitter.Hex()) + eventSig := utils.Keccak256Fixed([]byte("MessageSent(bytes)")) + if err := lp.RegisterFilter(logpoller.Filter{ + Name: filterName, + EventSigs: []common.Hash{eventSig}, + Addresses: []common.Address{transmitter}, + }); err != nil { + return nil, err + } + return &USDCReaderImpl{ + lggr: lggr, + lp: lp, + usdcMessageSent: eventSig, + filterName: filterName, + }, nil +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_mock.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_mock.go new file mode 100644 index 0000000000..b6f41895d1 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_mock.go @@ -0,0 +1,79 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package ccipdata + +import ( + context "context" + + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" +) + +// MockUSDCReader is an autogenerated mock type for the USDCReader type +type MockUSDCReader struct { + mock.Mock +} + +// Close provides a mock function with given fields: qopts +func (_m *MockUSDCReader) Close(qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) + + var r0 error + if rf, ok := ret.Get(0).(func(...pg.QOpt) error); ok { + r0 = rf(qopts...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetLastUSDCMessagePriorToLogIndexInTx provides a mock function with given fields: ctx, logIndex, txHash +func (_m *MockUSDCReader) GetLastUSDCMessagePriorToLogIndexInTx(ctx context.Context, logIndex int64, txHash common.Hash) ([]byte, error) { + ret := _m.Called(ctx, logIndex, txHash) + + var r0 []byte + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, int64, common.Hash) ([]byte, error)); ok { + return rf(ctx, logIndex, txHash) + } + if rf, ok := ret.Get(0).(func(context.Context, int64, common.Hash) []byte); ok { + r0 = rf(ctx, logIndex, txHash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, int64, common.Hash) error); ok { + r1 = rf(ctx, logIndex, txHash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +type mockConstructorTestingTNewMockUSDCReader interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockUSDCReader creates a new instance of MockUSDCReader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockUSDCReader(t mockConstructorTestingTNewMockUSDCReader) *MockUSDCReader { + mock := &MockUSDCReader{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go new file mode 100644 index 0000000000..d8e8db0ef6 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/internal/ccipdata/usdc_reader_test.go @@ -0,0 +1,87 @@ +package ccipdata + +import ( + "context" + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/stretchr/testify/assert" + "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" + "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/utils" +) + +func TestLogPollerClient_GetLastUSDCMessagePriorToLogIndexInTx(t *testing.T) { + txHash := utils.RandomAddress().Hash() + ccipLogIndex := int64(100) + + expectedData := "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000" + expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" + lggr := logger.TestLogger(t) + + t.Run("multiple found", func(t *testing.T) { + lp := lpmocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + u, err := NewUSDCReader(lggr, utils.RandomAddress(), lp) + require.NoError(t, err) + lp.On("IndexedLogsByTxHash", + u.usdcMessageSent, + txHash, + mock.Anything, + ).Return([]logpoller.Log{ + {LogIndex: ccipLogIndex - 2, Data: []byte("-2")}, + {LogIndex: ccipLogIndex - 1, Data: hexutil.MustDecode(expectedData)}, + {LogIndex: ccipLogIndex, Data: []byte("0")}, + {LogIndex: ccipLogIndex + 1, Data: []byte("1")}, + }, nil) + + usdcMessageData, err := u.GetLastUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, txHash) + assert.NoError(t, err) + assert.Equal(t, expectedPostParse, hexutil.Encode(usdcMessageData)) + lp.AssertExpectations(t) + }) + + t.Run("none found", func(t *testing.T) { + lp := lpmocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + u, err := NewUSDCReader(lggr, utils.RandomAddress(), lp) + require.NoError(t, err) + lp.On("IndexedLogsByTxHash", + u.usdcMessageSent, + txHash, + mock.Anything, + ).Return([]logpoller.Log{}, nil) + + usdcMessageData, err := u.GetLastUSDCMessagePriorToLogIndexInTx(context.Background(), ccipLogIndex, txHash) + assert.Errorf(t, err, fmt.Sprintf("no USDC message found prior to log index %d in tx %s", ccipLogIndex, txHash.Hex())) + assert.Nil(t, usdcMessageData) + + lp.AssertExpectations(t) + }) +} + +func TestParse(t *testing.T) { + expectedBody, err := hexutil.Decode("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000") + require.NoError(t, err) + + parsedBody, err := parseUSDCMessageSent(expectedBody) + require.NoError(t, err) + + expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" + + require.Equal(t, expectedPostParse, hexutil.Encode(parsedBody)) +} + +func TestUSDCReaderFilters(t *testing.T) { + assertFilterRegistration(t, new(lpmocks.LogPoller), func(lp *lpmocks.LogPoller, addr common.Address) Closer { + c, err := NewUSDCReader(logger.TestLogger(t), addr, lp) + require.NoError(t, err) + return c + }, 1) +} diff --git a/core/services/ocr2/plugins/ccip/internal/contractutil/loaders.go b/core/services/ocr2/plugins/ccip/internal/contractutil/loaders.go index 218bd2a00f..8a0caecfba 100644 --- a/core/services/ocr2/plugins/ccip/internal/contractutil/loaders.go +++ b/core/services/ocr2/plugins/ccip/internal/contractutil/loaders.go @@ -1,6 +1,7 @@ package contractutil import ( + "github.com/Masterminds/semver/v3" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/pkg/errors" @@ -15,28 +16,20 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/observability" ) -func LoadOnRamp(onRampAddress common.Address, pluginName string, client client.Client) (evm_2_evm_onramp.EVM2EVMOnRampInterface, error) { - err := ccipconfig.VerifyTypeAndVersion(onRampAddress, client, ccipconfig.EVM2EVMOnRamp) +func LoadOnRamp(onRampAddress common.Address, pluginName string, client client.Client) (evm_2_evm_onramp.EVM2EVMOnRampInterface, semver.Version, error) { + version, err := ccipconfig.VerifyTypeAndVersion(onRampAddress, client, ccipconfig.EVM2EVMOnRamp) if err != nil { - return nil, errors.Wrap(err, "Invalid onRamp contract") + return nil, semver.Version{}, errors.Wrap(err, "Invalid onRamp contract") } - return observability.NewObservedEvm2EvmOnRamp(onRampAddress, pluginName, client) -} -func LoadOnRampDynamicConfig(onRamp evm_2_evm_onramp.EVM2EVMOnRampInterface, client client.Client) (evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig, error) { - versionString, err := onRamp.TypeAndVersion(&bind.CallOpts{}) - if err != nil { - return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{}, err - } - - _, version, err := ccipconfig.ParseTypeAndVersion(versionString) - if err != nil { - return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{}, err - } + onRamp, err := observability.NewObservedEvm2EvmOnRamp(onRampAddress, pluginName, client) + return onRamp, version, err +} +func LoadOnRampDynamicConfig(onRamp evm_2_evm_onramp.EVM2EVMOnRampInterface, version semver.Version, client client.Client) (evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig, error) { opts := &bind.CallOpts{} - switch version { + switch version.String() { case "1.0.0": legacyOnramp, err := evm_2_evm_onramp_1_0_0.NewEVM2EVMOnRamp(onRamp.Address(), client) if err != nil { @@ -47,11 +40,16 @@ func LoadOnRampDynamicConfig(onRamp evm_2_evm_onramp.EVM2EVMOnRampInterface, cli return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{}, err } return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ - Router: legacyDynamicConfig.Router, - MaxTokensLength: legacyDynamicConfig.MaxTokensLength, - PriceRegistry: legacyDynamicConfig.PriceRegistry, - MaxDataSize: legacyDynamicConfig.MaxDataSize, - MaxGasLimit: uint32(legacyDynamicConfig.MaxGasLimit), + Router: legacyDynamicConfig.Router, + MaxTokensLength: legacyDynamicConfig.MaxTokensLength, + DestGasOverhead: 0, + DestGasPerPayloadByte: 0, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 0, + DestDataAvailabilityMultiplier: 0, + PriceRegistry: legacyDynamicConfig.PriceRegistry, + MaxDataSize: legacyDynamicConfig.MaxDataSize, + MaxGasLimit: uint32(legacyDynamicConfig.MaxGasLimit), }, nil case "1.1.0": legacyOnramp, err := evm_2_evm_onramp_1_1_0.NewEVM2EVMOnRamp(onRamp.Address(), client) @@ -63,13 +61,16 @@ func LoadOnRampDynamicConfig(onRamp evm_2_evm_onramp.EVM2EVMOnRampInterface, cli return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{}, err } return evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig{ - Router: legacyDynamicConfig.Router, - MaxTokensLength: legacyDynamicConfig.MaxTokensLength, - DestGasOverhead: legacyDynamicConfig.DestGasOverhead, - DestGasPerPayloadByte: legacyDynamicConfig.DestGasPerPayloadByte, - PriceRegistry: legacyDynamicConfig.PriceRegistry, - MaxDataSize: legacyDynamicConfig.MaxDataSize, - MaxGasLimit: uint32(legacyDynamicConfig.MaxGasLimit), + Router: legacyDynamicConfig.Router, + MaxTokensLength: legacyDynamicConfig.MaxTokensLength, + DestGasOverhead: legacyDynamicConfig.DestGasOverhead, + DestGasPerPayloadByte: legacyDynamicConfig.DestGasPerPayloadByte, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 0, + DestDataAvailabilityMultiplier: 0, + PriceRegistry: legacyDynamicConfig.PriceRegistry, + MaxDataSize: legacyDynamicConfig.MaxDataSize, + MaxGasLimit: uint32(legacyDynamicConfig.MaxGasLimit), }, nil case "1.2.0": return onRamp.GetDynamicConfig(opts) @@ -78,18 +79,22 @@ func LoadOnRampDynamicConfig(onRamp evm_2_evm_onramp.EVM2EVMOnRampInterface, cli } } -func LoadOffRamp(offRampAddress common.Address, pluginName string, client client.Client) (evm_2_evm_offramp.EVM2EVMOffRampInterface, error) { - err := ccipconfig.VerifyTypeAndVersion(offRampAddress, client, ccipconfig.EVM2EVMOffRamp) +func LoadOffRamp(offRampAddress common.Address, pluginName string, client client.Client) (evm_2_evm_offramp.EVM2EVMOffRampInterface, semver.Version, error) { + version, err := ccipconfig.VerifyTypeAndVersion(offRampAddress, client, ccipconfig.EVM2EVMOffRamp) if err != nil { - return nil, errors.Wrap(err, "Invalid offRamp contract") + return nil, semver.Version{}, errors.Wrap(err, "Invalid offRamp contract") } - return observability.NewObservedEvm2EvmOffRamp(offRampAddress, pluginName, client) + + offRamp, err := observability.NewObservedEvm2EvmOffRamp(offRampAddress, pluginName, client) + return offRamp, version, err } -func LoadCommitStore(commitStoreAddress common.Address, pluginName string, client client.Client) (commit_store.CommitStoreInterface, error) { - err := ccipconfig.VerifyTypeAndVersion(commitStoreAddress, client, ccipconfig.CommitStore) +func LoadCommitStore(commitStoreAddress common.Address, pluginName string, client client.Client) (commit_store.CommitStoreInterface, semver.Version, error) { + version, err := ccipconfig.VerifyTypeAndVersion(commitStoreAddress, client, ccipconfig.CommitStore) if err != nil { - return nil, errors.Wrap(err, "Invalid commitStore contract") + return nil, semver.Version{}, errors.Wrap(err, "Invalid commitStore contract") } - return observability.NewObservedCommitStore(commitStoreAddress, pluginName, client) + + commitStore, err := observability.NewObservedCommitStore(commitStoreAddress, pluginName, client) + return commitStore, version, err } diff --git a/core/services/ocr2/plugins/ccip/internal/contractutil/shortcuts.go b/core/services/ocr2/plugins/ccip/internal/contractutil/shortcuts.go index 1831030132..a6175d5561 100644 --- a/core/services/ocr2/plugins/ccip/internal/contractutil/shortcuts.go +++ b/core/services/ocr2/plugins/ccip/internal/contractutil/shortcuts.go @@ -1,28 +1,12 @@ package contractutil import ( - "context" "encoding/hex" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" ) -// IsCommitStoreDownNow Checks whether the commit store is down by doing an onchain check for Paused and ARM status -func IsCommitStoreDownNow(ctx context.Context, lggr logger.Logger, commitStore commit_store.CommitStoreInterface) bool { - unPausedAndHealthy, err := commitStore.IsUnpausedAndARMHealthy(&bind.CallOpts{Context: ctx}) - if err != nil { - // If we cannot read the state, assume the worst - lggr.Errorw("Unable to read CommitStore IsUnpausedAndARMHealthy", "err", err) - return true - } - return !unPausedAndHealthy -} - -func GetMessageIDsAsHexString(messages []evm_2_evm_offramp.InternalEVM2EVMMessage) []string { +func GetMessageIDsAsHexString(messages []internal.EVM2EVMMessage) []string { messageIDs := make([]string, 0, len(messages)) for _, m := range messages { messageIDs = append(messageIDs, "0x"+hex.EncodeToString(m.MessageId[:])) diff --git a/core/services/ocr2/plugins/ccip/internal/contractutil/shortcuts_test.go b/core/services/ocr2/plugins/ccip/internal/contractutil/shortcuts_test.go index 90794d256b..65ce496ba0 100644 --- a/core/services/ocr2/plugins/ccip/internal/contractutil/shortcuts_test.go +++ b/core/services/ocr2/plugins/ccip/internal/contractutil/shortcuts_test.go @@ -8,19 +8,19 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" ) func TestGetMessageIDsAsHexString(t *testing.T) { t.Run("base", func(t *testing.T) { - hashes := make([]common.Hash, 10) + hashes := make([]internal.Hash, 10) for i := range hashes { - hashes[i] = common.HexToHash(strconv.Itoa(rand.Intn(100000))) + hashes[i] = internal.Hash(common.HexToHash(strconv.Itoa(rand.Intn(100000)))) } - msgs := make([]evm_2_evm_offramp.InternalEVM2EVMMessage, len(hashes)) + msgs := make([]internal.EVM2EVMMessage, len(hashes)) for i := range msgs { - msgs[i] = evm_2_evm_offramp.InternalEVM2EVMMessage{MessageId: hashes[i]} + msgs[i] = internal.EVM2EVMMessage{MessageId: hashes[i]} } messageIDs := GetMessageIDsAsHexString(msgs) diff --git a/core/services/ocr2/plugins/ccip/internal/hashlib/common.go b/core/services/ocr2/plugins/ccip/internal/hashlib/common.go index aab70e5e0c..28a4405bb4 100644 --- a/core/services/ocr2/plugins/ccip/internal/hashlib/common.go +++ b/core/services/ocr2/plugins/ccip/internal/hashlib/common.go @@ -1,13 +1,6 @@ package hashlib import ( - "github.com/pkg/errors" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" - "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -23,31 +16,3 @@ func BytesOfBytesKeccak(b [][]byte) ([32]byte, error) { } return h, nil } - -// LeavesFromIntervals Extracts the hashed leaves from a given set of logs -func LeavesFromIntervals( - lggr logger.Logger, - interval commit_store.CommitStoreInterval, - hasher LeafHasherInterface[[32]byte], - sendReqs []ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested], -) ([][32]byte, error) { - var seqNrs []uint64 - for _, req := range sendReqs { - seqNrs = append(seqNrs, req.Data.Message.SequenceNumber) - } - - if !ccipcalc.ContiguousReqs(lggr, interval.Min, interval.Max, seqNrs) { - return nil, errors.Errorf("do not have full range [%v, %v] have %v", interval.Min, interval.Max, seqNrs) - } - var leaves [][32]byte - - for _, sendReq := range sendReqs { - hash, err2 := hasher.HashLeaf(sendReq.Data.Raw) - if err2 != nil { - return nil, err2 - } - leaves = append(leaves, hash) - } - - return leaves, nil -} diff --git a/core/services/ocr2/plugins/ccip/internal/hashlib/leaf_hasher.go b/core/services/ocr2/plugins/ccip/internal/hashlib/leaf_hasher.go deleted file mode 100644 index ac875d7965..0000000000 --- a/core/services/ocr2/plugins/ccip/internal/hashlib/leaf_hasher.go +++ /dev/null @@ -1,106 +0,0 @@ -package hashlib - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/math" - "github.com/ethereum/go-ethereum/core/types" - - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - "github.com/smartcontractkit/chainlink/v2/core/utils" -) - -type LeafHasherInterface[H Hash] interface { - HashLeaf(log types.Log) (H, error) -} - -var LeafDomainSeparator = [1]byte{0x00} - -func GetMetaDataHash[H Hash](ctx Ctx[H], prefix [32]byte, sourceChainSelector uint64, onRampId common.Address, destChainSelector uint64) H { - paddedOnRamp := onRampId.Hash() - return ctx.Hash(utils.ConcatBytes(prefix[:], math.U256Bytes(big.NewInt(0).SetUint64(sourceChainSelector)), math.U256Bytes(big.NewInt(0).SetUint64(destChainSelector)), paddedOnRamp[:])) -} - -type LeafHasher struct { - metaDataHash [32]byte - ctx Ctx[[32]byte] -} - -func NewLeafHasher(sourceChainSelector uint64, destChainSelector uint64, onRampId common.Address, ctx Ctx[[32]byte]) *LeafHasher { - return &LeafHasher{ - metaDataHash: GetMetaDataHash(ctx, ctx.Hash([]byte("EVM2EVMMessageHashV2")), sourceChainSelector, onRampId, destChainSelector), - ctx: ctx, - } -} - -var _ LeafHasherInterface[[32]byte] = &LeafHasher{} - -func (t *LeafHasher) HashLeaf(log types.Log) ([32]byte, error) { - message, err := abihelpers.DecodeOffRampMessage(log.Data) - if err != nil { - return [32]byte{}, err - } - - encodedTokens, err := abihelpers.TokenAmountsArgs.PackValues([]interface{}{message.TokenAmounts}) - if err != nil { - return [32]byte{}, err - } - - bytesArray, err := abi.NewType("bytes[]", "bytes[]", nil) - if err != nil { - return [32]byte{}, err - } - - encodedSourceTokenData, err := abi.Arguments{abi.Argument{Type: bytesArray}}.PackValues([]interface{}{message.SourceTokenData}) - if err != nil { - return [32]byte{}, err - } - - packedFixedSizeValues, err := utils.ABIEncode( - `[ -{"name": "sender", "type":"address"}, -{"name": "receiver", "type":"address"}, -{"name": "sequenceNumber", "type":"uint64"}, -{"name": "gasLimit", "type":"uint256"}, -{"name": "strict", "type":"bool"}, -{"name": "nonce", "type":"uint64"}, -{"name": "feeToken","type": "address"}, -{"name": "feeTokenAmount","type": "uint256"} -]`, - message.Sender, - message.Receiver, - message.SequenceNumber, - message.GasLimit, - message.Strict, - message.Nonce, - message.FeeToken, - message.FeeTokenAmount, - ) - if err != nil { - return [32]byte{}, err - } - fixedSizeValuesHash := t.ctx.Hash(packedFixedSizeValues) - - packedValues, err := utils.ABIEncode( - `[ -{"name": "leafDomainSeparator","type":"bytes1"}, -{"name": "metadataHash", "type":"bytes32"}, -{"name": "fixedSizeValuesHash", "type":"bytes32"}, -{"name": "dataHash", "type":"bytes32"}, -{"name": "tokenAmountsHash", "type":"bytes32"}, -{"name": "sourceTokenDataHash", "type":"bytes32"} -]`, - LeafDomainSeparator, - t.metaDataHash, - fixedSizeValuesHash, - t.ctx.Hash(message.Data), - t.ctx.Hash(encodedTokens), - t.ctx.Hash(encodedSourceTokenData), - ) - if err != nil { - return [32]byte{}, err - } - return t.ctx.Hash(packedValues), nil -} diff --git a/core/services/ocr2/plugins/ccip/internal/models.go b/core/services/ocr2/plugins/ccip/internal/models.go index b9eee7bea4..c4c5447f1e 100644 --- a/core/services/ocr2/plugins/ccip/internal/models.go +++ b/core/services/ocr2/plugins/ccip/internal/models.go @@ -1,19 +1,51 @@ package internal import ( + "math/big" "time" "github.com/ethereum/go-ethereum/common" - - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" + "github.com/ethereum/go-ethereum/common/hexutil" ) // EVM2EVMOnRampCCIPSendRequestedWithMeta helper struct to hold the send request and some metadata type EVM2EVMOnRampCCIPSendRequestedWithMeta struct { - evm_2_evm_offramp.InternalEVM2EVMMessage + EVM2EVMMessage BlockTimestamp time.Time Executed bool Finalized bool LogIndex uint TxHash common.Hash } + +type Hash [32]byte + +func (h Hash) String() string { + return hexutil.Encode(h[:]) +} + +type TokenAmount struct { + Token common.Address + Amount *big.Int +} + +// EVM2EVMMessage is the interface for a message sent from the offramp to the onramp +// Plugin can operate against any lane version which has a message satisfying this interface. +type EVM2EVMMessage struct { + SequenceNumber uint64 + GasLimit *big.Int + Nonce uint64 + MessageId Hash + SourceChainSelector uint64 + Sender common.Address + Receiver common.Address + Strict bool + FeeToken common.Address + FeeTokenAmount *big.Int + Data []byte + TokenAmounts []TokenAmount + SourceTokenData [][]byte + + // Computed + Hash Hash +} diff --git a/core/services/ocr2/plugins/ccip/observability/price_registry.go b/core/services/ocr2/plugins/ccip/observability/price_registry.go index ed02bc01d4..1087e132ff 100644 --- a/core/services/ocr2/plugins/ccip/observability/price_registry.go +++ b/core/services/ocr2/plugins/ccip/observability/price_registry.go @@ -9,19 +9,19 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" ) -type ObservedPriceRegistry struct { - price_registry.PriceRegistryInterface +type ObservedPriceRegistryV1_0_0 struct { + *price_registry.PriceRegistry metric metricDetails } -func NewObservedPriceRegistry(address common.Address, pluginName string, client client.Client) (price_registry.PriceRegistryInterface, error) { +func NewObservedPriceRegistryV1_0_0(address common.Address, pluginName string, client client.Client) (*ObservedPriceRegistryV1_0_0, error) { priceRegistry, err := price_registry.NewPriceRegistry(address, client) if err != nil { return nil, err } - return &ObservedPriceRegistry{ - PriceRegistryInterface: priceRegistry, + return &ObservedPriceRegistryV1_0_0{ + PriceRegistry: priceRegistry, metric: metricDetails{ histogram: priceRegistryHistogram, pluginName: pluginName, @@ -30,26 +30,26 @@ func NewObservedPriceRegistry(address common.Address, pluginName string, client }, nil } -func (o *ObservedPriceRegistry) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { +func (o *ObservedPriceRegistryV1_0_0) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { return withObservedContract(o.metric, "GetFeeTokens", func() ([]common.Address, error) { - return o.PriceRegistryInterface.GetFeeTokens(opts) + return o.PriceRegistry.GetFeeTokens(opts) }) } -func (o *ObservedPriceRegistry) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error) { +func (o *ObservedPriceRegistryV1_0_0) GetTokenPrices(opts *bind.CallOpts, tokens []common.Address) ([]price_registry.InternalTimestampedPackedUint224, error) { return withObservedContract(o.metric, "GetTokenPrices", func() ([]price_registry.InternalTimestampedPackedUint224, error) { - return o.PriceRegistryInterface.GetTokenPrices(opts, tokens) + return o.PriceRegistry.GetTokenPrices(opts, tokens) }) } -func (o *ObservedPriceRegistry) ParseUsdPerUnitGasUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error) { +func (o *ObservedPriceRegistryV1_0_0) ParseUsdPerUnitGasUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error) { return withObservedContract(o.metric, "ParseUsdPerUnitGasUpdated", func() (*price_registry.PriceRegistryUsdPerUnitGasUpdated, error) { - return o.PriceRegistryInterface.ParseUsdPerUnitGasUpdated(log) + return o.PriceRegistry.ParseUsdPerUnitGasUpdated(log) }) } -func (o *ObservedPriceRegistry) ParseUsdPerTokenUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error) { +func (o *ObservedPriceRegistryV1_0_0) ParseUsdPerTokenUpdated(log types.Log) (*price_registry.PriceRegistryUsdPerTokenUpdated, error) { return withObservedContract(o.metric, "ParseUsdPerTokenUpdated", func() (*price_registry.PriceRegistryUsdPerTokenUpdated, error) { - return o.PriceRegistryInterface.ParseUsdPerTokenUpdated(log) + return o.PriceRegistry.ParseUsdPerTokenUpdated(log) }) } diff --git a/core/services/ocr2/plugins/ccip/observations.go b/core/services/ocr2/plugins/ccip/observations.go index fa8c3abbf0..96c8be6e40 100644 --- a/core/services/ocr2/plugins/ccip/observations.go +++ b/core/services/ocr2/plugins/ccip/observations.go @@ -7,14 +7,14 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) type CommitObservation struct { - Interval commit_store.CommitStoreInterval `json:"interval"` - TokenPricesUSD map[common.Address]*big.Int `json:"tokensPerFeeCoin"` - SourceGasPriceUSD *big.Int `json:"sourceGasPrice"` + Interval ccipdata.CommitStoreInterval `json:"interval"` + TokenPricesUSD map[common.Address]*big.Int `json:"tokensPerFeeCoin"` + SourceGasPriceUSD *big.Int `json:"sourceGasPrice"` } func (o CommitObservation) Marshal() ([]byte, error) { diff --git a/core/services/ocr2/plugins/ccip/observations_test.go b/core/services/ocr2/plugins/ccip/observations_test.go index 332a519397..987a3de4bc 100644 --- a/core/services/ocr2/plugins/ccip/observations_test.go +++ b/core/services/ocr2/plugins/ccip/observations_test.go @@ -10,13 +10,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/commit_store" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" ) func TestObservationFilter(t *testing.T) { lggr := logger.TestLogger(t) - obs1 := CommitObservation{Interval: commit_store.CommitStoreInterval{Min: 1, Max: 10}} + obs1 := CommitObservation{Interval: ccipdata.CommitStoreInterval{Min: 1, Max: 10}} b1, err := obs1.Marshal() require.NoError(t, err) nonEmpty := getParsableObservations[CommitObservation](lggr, []types.AttributedObservation{{Observation: b1}, {Observation: []byte{}}}) diff --git a/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go new file mode 100644 index 0000000000..af6a92f0c6 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go @@ -0,0 +1,184 @@ +package prices + +import ( + "context" + "fmt" + "math/big" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +type DAGasPriceEstimator struct { + execEstimator GasPriceEstimator + l1Oracle rollups.L1Oracle + priceEncodingLength uint + daDeviationPPB int64 + daOverheadGas int64 + gasPerDAByte int64 + daMultiplier int64 +} + +func NewDAGasPriceEstimator( + estimator gas.EvmFeeEstimator, + maxGasPrice *big.Int, + deviationPPB int64, + daDeviationPPB int64, +) DAGasPriceEstimator { + return DAGasPriceEstimator{ + execEstimator: NewExecGasPriceEstimator(estimator, maxGasPrice, deviationPPB), + l1Oracle: estimator.L1Oracle(), + priceEncodingLength: daGasPriceEncodingLength, + daDeviationPPB: daDeviationPPB, + } +} + +func (g DAGasPriceEstimator) GetGasPrice(ctx context.Context) (GasPrice, error) { + execGasPrice, err := g.execEstimator.GetGasPrice(ctx) + if err != nil { + return nil, err + } + var gasPrice *big.Int = execGasPrice + if gasPrice.BitLen() > int(g.priceEncodingLength) { + return nil, fmt.Errorf("native gas price exceeded max range %+v", gasPrice) + } + + if g.l1Oracle == nil { + return gasPrice, nil + } + + daGasPriceWei, err := g.l1Oracle.GasPrice(ctx) + if err != nil { + return nil, err + } + + if daGasPrice := daGasPriceWei.ToInt(); daGasPrice.Cmp(big.NewInt(0)) > 0 { + if daGasPrice.BitLen() > int(g.priceEncodingLength) { + return nil, fmt.Errorf("data availability gas price exceeded max range %+v", daGasPrice) + } + + daGasPrice = new(big.Int).Lsh(daGasPrice, g.priceEncodingLength) + gasPrice = new(big.Int).Add(gasPrice, daGasPrice) + } + + return gasPrice, nil +} + +func (g DAGasPriceEstimator) DenoteInUSD(p GasPrice, wrappedNativePrice *big.Int) (GasPrice, error) { + daGasPrice, execGasPrice, err := g.parseEncodedGasPrice(p) + if err != nil { + return nil, err + } + + // This assumes l1GasPrice is priced using the same native token as l2 native + daUSD := ccipcalc.CalculateUsdPerUnitGas(daGasPrice, wrappedNativePrice) + if daUSD.BitLen() > int(g.priceEncodingLength) { + return nil, fmt.Errorf("data availability gas price USD exceeded max range %+v", daUSD) + } + execUSD := ccipcalc.CalculateUsdPerUnitGas(execGasPrice, wrappedNativePrice) + if execUSD.BitLen() > int(g.priceEncodingLength) { + return nil, fmt.Errorf("exec gas price USD exceeded max range %+v", execUSD) + } + + daUSD = new(big.Int).Lsh(daUSD, g.priceEncodingLength) + return new(big.Int).Add(daUSD, execUSD), nil +} + +func (g DAGasPriceEstimator) Median(gasPrices []GasPrice) (GasPrice, error) { + daPrices := make([]*big.Int, len(gasPrices)) + execPrices := make([]*big.Int, len(gasPrices)) + + for i := range gasPrices { + daGasPrice, execGasPrice, err := g.parseEncodedGasPrice(gasPrices[i]) + if err != nil { + return nil, err + } + + daPrices[i] = daGasPrice + execPrices[i] = execGasPrice + } + + daMedian := ccipcalc.BigIntMedian(daPrices) + execMedian := ccipcalc.BigIntMedian(execPrices) + + daMedian = new(big.Int).Lsh(daMedian, g.priceEncodingLength) + return new(big.Int).Add(daMedian, execMedian), nil +} + +func (g DAGasPriceEstimator) Deviates(p1 GasPrice, p2 GasPrice) (bool, error) { + p1DAGasPrice, p1ExecGasPrice, err := g.parseEncodedGasPrice(p1) + if err != nil { + return false, err + } + p2DAGasPrice, p2ExecGasPrice, err := g.parseEncodedGasPrice(p2) + if err != nil { + return false, err + } + + execDeviates, err := g.execEstimator.Deviates(p1ExecGasPrice, p2ExecGasPrice) + if err != nil { + return false, err + } + if execDeviates { + return execDeviates, nil + } + + return ccipcalc.Deviates(p1DAGasPrice, p2DAGasPrice, g.daDeviationPPB), nil +} + +func (g DAGasPriceEstimator) EstimateMsgCostUSD(p GasPrice, wrappedNativePrice *big.Int, msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) { + daGasPrice, execGasPrice, err := g.parseEncodedGasPrice(p) + if err != nil { + return nil, err + } + + execCostUSD, err := g.execEstimator.EstimateMsgCostUSD(execGasPrice, wrappedNativePrice, msg) + if err != nil { + return nil, err + } + + // If there is data availability price component, then include data availability cost in fee estimation + if daGasPrice.Cmp(big.NewInt(0)) > 0 { + daGasCostUSD := g.estimateDACostUSD(daGasPrice, wrappedNativePrice, msg) + execCostUSD = new(big.Int).Add(daGasCostUSD, execCostUSD) + } + return execCostUSD, nil +} + +func (g DAGasPriceEstimator) String(p GasPrice) string { + daGasPrice, execGasPrice, err := g.parseEncodedGasPrice(p) + if err != nil { + return err.Error() + } + return fmt.Sprintf("DA Price: %s, Exec Price: %s", daGasPrice, execGasPrice) +} + +func (g DAGasPriceEstimator) parseEncodedGasPrice(p *big.Int) (*big.Int, *big.Int, error) { + if p.BitLen() > int(g.priceEncodingLength*2) { + return nil, nil, fmt.Errorf("encoded gas price exceeded max range %+v", p) + } + + daGasPrice := new(big.Int).Rsh(p, g.priceEncodingLength) + + daStart := new(big.Int).Lsh(big.NewInt(1), g.priceEncodingLength) + execGasPrice := new(big.Int).Mod(p, daStart) + + return daGasPrice, execGasPrice, nil +} + +func (g DAGasPriceEstimator) estimateDACostUSD(daGasPrice GasPrice, wrappedNativePrice *big.Int, msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) *big.Int { + var sourceTokenDataLen int + for _, tokenData := range msg.SourceTokenData { + sourceTokenDataLen += len(tokenData) + } + + dataLen := evmMessageFixedBytes + len(msg.Data) + len(msg.TokenAmounts)*evmMessageBytesPerToken + sourceTokenDataLen + dataGas := big.NewInt(int64(dataLen)*g.gasPerDAByte + g.daOverheadGas) + + dataGasEstimate := new(big.Int).Mul(dataGas, daGasPrice) + dataGasEstimate = new(big.Int).Div(new(big.Int).Mul(dataGasEstimate, big.NewInt(g.daMultiplier)), big.NewInt(daMultiplierBase)) + + return ccipcalc.CalculateUsdPerUnitGas(dataGasEstimate, wrappedNativePrice) +} diff --git a/core/services/ocr2/plugins/ccip/prices/da_price_estimator_test.go b/core/services/ocr2/plugins/ccip/prices/da_price_estimator_test.go new file mode 100644 index 0000000000..d8d4a661e0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/da_price_estimator_test.go @@ -0,0 +1,451 @@ +package prices + +import ( + "context" + "math/big" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "github.com/smartcontractkit/chainlink/v2/core/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" +) + +func encodeGasPrice(daPrice, execPrice *big.Int) *big.Int { + return new(big.Int).Add(new(big.Int).Lsh(daPrice, daGasPriceEncodingLength), execPrice) +} + +func TestDAPriceEstimator_GetGasPrice(t *testing.T) { + ctx := context.Background() + + testCases := []struct { + name string + daGasPrice GasPrice + execGasPrice GasPrice + expPrice GasPrice + expErr bool + }{ + { + name: "base", + daGasPrice: big.NewInt(1), + execGasPrice: big.NewInt(0), + expPrice: encodeGasPrice(big.NewInt(1), big.NewInt(0)), + expErr: false, + }, + { + name: "large values", + daGasPrice: big.NewInt(1e9), // 1 gwei + execGasPrice: big.NewInt(200e9), // 200 gwei + expPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(200e9)), + expErr: false, + }, + { + name: "zero DA price", + daGasPrice: big.NewInt(0), + execGasPrice: big.NewInt(200e9), + expPrice: encodeGasPrice(big.NewInt(0), big.NewInt(200e9)), + expErr: false, + }, + { + name: "zero exec price", + daGasPrice: big.NewInt(1e9), + execGasPrice: big.NewInt(0), + expPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), + expErr: false, + }, + { + name: "price out of bounds", + daGasPrice: new(big.Int).Lsh(big.NewInt(1), daGasPriceEncodingLength), + execGasPrice: big.NewInt(1), + expPrice: nil, + expErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + execEstimator := NewMockGasPriceEstimator(t) + execEstimator.On("GetGasPrice", ctx).Return(tc.execGasPrice, nil) + + l1Oracle := mocks.NewL1Oracle(t) + l1Oracle.On("GasPrice", ctx).Return(assets.NewWei(tc.daGasPrice), nil) + + g := DAGasPriceEstimator{ + execEstimator: execEstimator, + l1Oracle: l1Oracle, + priceEncodingLength: daGasPriceEncodingLength, + } + + gasPrice, err := g.GetGasPrice(ctx) + if tc.expErr { + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, tc.expPrice, gasPrice) + }) + } + + t.Run("nil L1 oracle", func(t *testing.T) { + var expPrice GasPrice = big.NewInt(1) + + execEstimator := NewMockGasPriceEstimator(t) + execEstimator.On("GetGasPrice", ctx).Return(expPrice, nil) + + g := DAGasPriceEstimator{ + execEstimator: execEstimator, + l1Oracle: nil, + priceEncodingLength: daGasPriceEncodingLength, + } + + gasPrice, err := g.GetGasPrice(ctx) + assert.NoError(t, err) + assert.Equal(t, expPrice, gasPrice) + }) +} + +func TestDAPriceEstimator_DenoteInUSD(t *testing.T) { + val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } + + testCases := []struct { + name string + gasPrice GasPrice + nativePrice *big.Int + expPrice GasPrice + }{ + { + name: "base", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(10e9)), + nativePrice: val1e18(2_000), + expPrice: encodeGasPrice(big.NewInt(2000e9), big.NewInt(20000e9)), + }, + { + name: "low price truncates to 0", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(10e9)), + nativePrice: big.NewInt(1), + expPrice: big.NewInt(0), + }, + { + name: "high price", + gasPrice: encodeGasPrice(val1e18(1), val1e18(10)), + nativePrice: val1e18(2000), + expPrice: encodeGasPrice(val1e18(2_000), val1e18(20_000)), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := DAGasPriceEstimator{ + priceEncodingLength: daGasPriceEncodingLength, + } + + gasPrice, err := g.DenoteInUSD(tc.gasPrice, tc.nativePrice) + assert.NoError(t, err) + assert.True(t, ((*big.Int)(tc.expPrice)).Cmp(gasPrice) == 0) + }) + } +} + +func TestDAPriceEstimator_Median(t *testing.T) { + val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } + + testCases := []struct { + name string + gasPrices []GasPrice + expMedian GasPrice + }{ + { + name: "base", + gasPrices: []GasPrice{ + encodeGasPrice(big.NewInt(1), big.NewInt(1)), + encodeGasPrice(big.NewInt(2), big.NewInt(2)), + encodeGasPrice(big.NewInt(3), big.NewInt(3)), + }, + expMedian: encodeGasPrice(big.NewInt(2), big.NewInt(2)), + }, + { + name: "median 2", + gasPrices: []GasPrice{ + encodeGasPrice(big.NewInt(1), big.NewInt(1)), + encodeGasPrice(big.NewInt(2), big.NewInt(2)), + }, + expMedian: encodeGasPrice(big.NewInt(2), big.NewInt(2)), + }, + { + name: "large values", + gasPrices: []GasPrice{ + encodeGasPrice(val1e18(5), val1e18(5)), + encodeGasPrice(val1e18(4), val1e18(4)), + encodeGasPrice(val1e18(3), val1e18(3)), + encodeGasPrice(val1e18(2), val1e18(2)), + encodeGasPrice(val1e18(1), val1e18(1)), + }, + expMedian: encodeGasPrice(val1e18(3), val1e18(3)), + }, + { + name: "zeros", + gasPrices: []GasPrice{big.NewInt(0), big.NewInt(0), big.NewInt(0)}, + expMedian: big.NewInt(0), + }, + { + name: "picks median of each price component individually", + gasPrices: []GasPrice{ + encodeGasPrice(val1e18(1), val1e18(3)), + encodeGasPrice(val1e18(2), val1e18(2)), + encodeGasPrice(val1e18(3), val1e18(1)), + }, + expMedian: encodeGasPrice(val1e18(2), val1e18(2)), + }, + { + name: "unsorted even number of price components", + gasPrices: []GasPrice{ + encodeGasPrice(val1e18(1), val1e18(22)), + encodeGasPrice(val1e18(4), val1e18(33)), + encodeGasPrice(val1e18(2), val1e18(44)), + encodeGasPrice(val1e18(3), val1e18(11)), + }, + expMedian: encodeGasPrice(val1e18(3), val1e18(33)), + }, + { + name: "equal DA price components", + gasPrices: []GasPrice{ + encodeGasPrice(val1e18(2), val1e18(22)), + encodeGasPrice(val1e18(2), val1e18(33)), + encodeGasPrice(val1e18(2), val1e18(44)), + encodeGasPrice(val1e18(2), val1e18(11)), + }, + expMedian: encodeGasPrice(val1e18(2), val1e18(33)), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := DAGasPriceEstimator{ + priceEncodingLength: daGasPriceEncodingLength, + } + + gasPrice, err := g.Median(tc.gasPrices) + assert.NoError(t, err) + assert.True(t, ((*big.Int)(tc.expMedian)).Cmp(gasPrice) == 0) + }) + } +} + +func TestDAPriceEstimator_Deviates(t *testing.T) { + testCases := []struct { + name string + gasPrice1 GasPrice + gasPrice2 GasPrice + daDeviationPPB int64 + execDeviationPPB int64 + expDeviates bool + }{ + { + name: "base", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(79e8), big.NewInt(79e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "negative difference also deviates", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(121e8), big.NewInt(121e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "only DA component deviates", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(150e8), big.NewInt(110e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "only exec component deviates", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(110e8), big.NewInt(150e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "both do not deviate", + gasPrice1: encodeGasPrice(big.NewInt(100e8), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(110e8), big.NewInt(110e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: false, + }, + { + name: "zero DA price and exec deviates", + gasPrice1: encodeGasPrice(big.NewInt(0), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(0), big.NewInt(121e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: true, + }, + { + name: "zero DA price and exec does not deviate", + gasPrice1: encodeGasPrice(big.NewInt(0), big.NewInt(100e8)), + gasPrice2: encodeGasPrice(big.NewInt(0), big.NewInt(110e8)), + daDeviationPPB: 2e8, + execDeviationPPB: 2e8, + expDeviates: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := DAGasPriceEstimator{ + execEstimator: ExecGasPriceEstimator{ + deviationPPB: tc.execDeviationPPB, + }, + daDeviationPPB: tc.daDeviationPPB, + priceEncodingLength: daGasPriceEncodingLength, + } + + deviated, err := g.Deviates(tc.gasPrice1, tc.gasPrice2) + assert.NoError(t, err) + if tc.expDeviates { + assert.True(t, deviated) + } else { + assert.False(t, deviated) + } + }) + } +} + +func TestDAPriceEstimator_EstimateMsgCostUSD(t *testing.T) { + execCostUSD := big.NewInt(100_000) + + testCases := []struct { + name string + gasPrice GasPrice + wrappedNativePrice *big.Int + msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta + daOverheadGas int64 + gasPerDAByte int64 + daMultiplier int64 + expUSD *big.Int + }{ + { + name: "only DA overhead", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + Data: []byte{}, + TokenAmounts: []internal.TokenAmount{}, + SourceTokenData: [][]byte{}, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 0, + daMultiplier: 10_000, // 1x multiplier + expUSD: new(big.Int).Add(execCostUSD, big.NewInt(100_000e9)), + }, + { + name: "include message data gas", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + Data: make([]byte, 1_000), + TokenAmounts: make([]internal.TokenAmount, 5), + SourceTokenData: [][]byte{ + make([]byte, 10), make([]byte, 10), make([]byte, 10), make([]byte, 10), make([]byte, 10), + }, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 16, + daMultiplier: 10_000, // 1x multiplier + expUSD: new(big.Int).Add(execCostUSD, big.NewInt(134_208e9)), + }, + { + name: "zero DA price", + gasPrice: big.NewInt(0), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + Data: []byte{}, + TokenAmounts: []internal.TokenAmount{}, + SourceTokenData: [][]byte{}, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 16, + daMultiplier: 10_000, // 1x multiplier + expUSD: execCostUSD, + }, + { + name: "double native price", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(2e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + Data: []byte{}, + TokenAmounts: []internal.TokenAmount{}, + SourceTokenData: [][]byte{}, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 0, + daMultiplier: 10_000, // 1x multiplier + expUSD: new(big.Int).Add(execCostUSD, big.NewInt(200_000e9)), + }, + { + name: "half multiplier", + gasPrice: encodeGasPrice(big.NewInt(1e9), big.NewInt(0)), // 1 gwei DA price, 0 exec price + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + Data: []byte{}, + TokenAmounts: []internal.TokenAmount{}, + SourceTokenData: [][]byte{}, + }, + }, + daOverheadGas: 100_000, + gasPerDAByte: 0, + daMultiplier: 5_000, // 0.5x multiplier + expUSD: new(big.Int).Add(execCostUSD, big.NewInt(50_000e9)), + }, + } + + for _, tc := range testCases { + execEstimator := NewMockGasPriceEstimator(t) + execEstimator.On("EstimateMsgCostUSD", mock.Anything, tc.wrappedNativePrice, tc.msg).Return(execCostUSD, nil) + + t.Run(tc.name, func(t *testing.T) { + g := DAGasPriceEstimator{ + execEstimator: execEstimator, + l1Oracle: nil, + priceEncodingLength: daGasPriceEncodingLength, + daOverheadGas: tc.daOverheadGas, + gasPerDAByte: tc.gasPerDAByte, + daMultiplier: tc.daMultiplier, + } + + costUSD, err := g.EstimateMsgCostUSD(tc.gasPrice, tc.wrappedNativePrice, tc.msg) + assert.NoError(t, err) + assert.Equal(t, tc.expUSD, costUSD) + }) + } +} + +func TestDAPriceEstimator_String(t *testing.T) { + g := DAGasPriceEstimator{ + execEstimator: nil, + l1Oracle: nil, + priceEncodingLength: daGasPriceEncodingLength, + } + + str := g.String(encodeGasPrice(big.NewInt(1), big.NewInt(2))) + assert.Equal(t, "DA Price: 1, Exec Price: 2", str) +} diff --git a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go new file mode 100644 index 0000000000..388e3a3f45 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go @@ -0,0 +1,75 @@ +package prices + +import ( + "context" + "fmt" + "math/big" + + "github.com/smartcontractkit/chainlink/v2/core/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" +) + +type ExecGasPriceEstimator struct { + estimator gas.EvmFeeEstimator + maxGasPrice *big.Int + deviationPPB int64 +} + +func NewExecGasPriceEstimator(estimator gas.EvmFeeEstimator, maxGasPrice *big.Int, deviationPPB int64) ExecGasPriceEstimator { + return ExecGasPriceEstimator{ + estimator: estimator, + maxGasPrice: maxGasPrice, + deviationPPB: deviationPPB, + } +} + +func (g ExecGasPriceEstimator) GetGasPrice(ctx context.Context) (GasPrice, error) { + gasPriceWei, _, err := g.estimator.GetFee(ctx, nil, 0, assets.NewWei(g.maxGasPrice)) + if err != nil { + return nil, err + } + // Use legacy if no dynamic is available. + gasPrice := gasPriceWei.Legacy.ToInt() + if gasPriceWei.DynamicFeeCap != nil { + gasPrice = gasPriceWei.DynamicFeeCap.ToInt() + } + if gasPrice == nil { + return nil, fmt.Errorf("missing gas price %+v", gasPriceWei) + } + + return gasPrice, nil +} + +func (g ExecGasPriceEstimator) DenoteInUSD(p GasPrice, wrappedNativePrice *big.Int) (GasPrice, error) { + return ccipcalc.CalculateUsdPerUnitGas(p, wrappedNativePrice), nil +} + +func (g ExecGasPriceEstimator) Median(gasPrices []GasPrice) (GasPrice, error) { + var prices []*big.Int + for _, p := range gasPrices { + prices = append(prices, p) + } + + return ccipcalc.BigIntMedian(prices), nil +} + +func (g ExecGasPriceEstimator) Deviates(p1 GasPrice, p2 GasPrice) (bool, error) { + return ccipcalc.Deviates(p1, p2, g.deviationPPB), nil +} + +func (g ExecGasPriceEstimator) EstimateMsgCostUSD(p GasPrice, wrappedNativePrice *big.Int, msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) { + execGasAmount := new(big.Int).Add(big.NewInt(feeBoostingOverheadGas), msg.GasLimit) + execGasAmount = new(big.Int).Add(execGasAmount, new(big.Int).Mul(big.NewInt(int64(len(msg.Data))), big.NewInt(execGasPerPayloadByte))) + execGasAmount = new(big.Int).Add(execGasAmount, new(big.Int).Mul(big.NewInt(int64(len(msg.TokenAmounts))), big.NewInt(execGasPerToken))) + + execGasCost := new(big.Int).Mul(execGasAmount, p) + + return ccipcalc.CalculateUsdPerUnitGas(execGasCost, wrappedNativePrice), nil +} + +func (g ExecGasPriceEstimator) String(p GasPrice) string { + var pi *big.Int = p + return pi.String() +} diff --git a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go new file mode 100644 index 0000000000..19b1b83115 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator_test.go @@ -0,0 +1,358 @@ +package prices + +import ( + "context" + "math/big" + "testing" + + "github.com/pkg/errors" + "github.com/stretchr/testify/assert" + + "github.com/smartcontractkit/chainlink/v2/core/assets" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" +) + +func TestExecPriceEstimator_GetGasPrice(t *testing.T) { + ctx := context.Background() + + testCases := []struct { + name string + sourceFeeEstimatorRespFee gas.EvmFee + sourceFeeEstimatorRespErr error + maxGasPrice *big.Int + expPrice GasPrice + expErr bool + }{ + { + name: "gets legacy gas price", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: assets.NewWei(big.NewInt(10)), + DynamicFeeCap: nil, + }, + sourceFeeEstimatorRespErr: nil, + maxGasPrice: big.NewInt(1), + expPrice: big.NewInt(10), + expErr: false, + }, + { + name: "gets dynamic gas price", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: nil, + DynamicFeeCap: assets.NewWei(big.NewInt(20)), + }, + sourceFeeEstimatorRespErr: nil, + maxGasPrice: big.NewInt(1), + expPrice: big.NewInt(20), + expErr: false, + }, + { + name: "gets dynamic gas price over legacy gas price", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: assets.NewWei(big.NewInt(10)), + DynamicFeeCap: assets.NewWei(big.NewInt(20)), + }, + sourceFeeEstimatorRespErr: nil, + maxGasPrice: big.NewInt(1), + expPrice: big.NewInt(20), + expErr: false, + }, + { + name: "fee estimator error", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: assets.NewWei(big.NewInt(10)), + DynamicFeeCap: nil, + }, + sourceFeeEstimatorRespErr: errors.New("fee estimator error"), + maxGasPrice: big.NewInt(1), + expPrice: nil, + expErr: true, + }, + { + name: "nil gas price error", + sourceFeeEstimatorRespFee: gas.EvmFee{ + Legacy: nil, + DynamicFeeCap: nil, + }, + sourceFeeEstimatorRespErr: nil, + maxGasPrice: big.NewInt(1), + expPrice: nil, + expErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sourceFeeEstimator := mocks.NewEvmFeeEstimator(t) + sourceFeeEstimator.On("GetFee", ctx, []byte(nil), uint32(0), assets.NewWei(tc.maxGasPrice)).Return( + tc.sourceFeeEstimatorRespFee, uint32(0), tc.sourceFeeEstimatorRespErr) + + g := ExecGasPriceEstimator{ + estimator: sourceFeeEstimator, + maxGasPrice: tc.maxGasPrice, + } + + gasPrice, err := g.GetGasPrice(ctx) + if tc.expErr { + assert.Nil(t, gasPrice) + assert.Error(t, err) + return + } + assert.NoError(t, err) + assert.Equal(t, tc.expPrice, gasPrice) + }) + } +} + +func TestExecPriceEstimator_DenoteInUSD(t *testing.T) { + val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } + + testCases := []struct { + name string + gasPrice GasPrice + nativePrice *big.Int + expPrice GasPrice + }{ + { + name: "base", + gasPrice: big.NewInt(1e9), + nativePrice: val1e18(2_000), + expPrice: big.NewInt(2_000e9), + }, + { + name: "low price truncates to 0", + gasPrice: big.NewInt(1e9), + nativePrice: big.NewInt(1), + expPrice: big.NewInt(0), + }, + { + name: "high price", + gasPrice: val1e18(1), + nativePrice: val1e18(2_000), + expPrice: val1e18(2_000), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := ExecGasPriceEstimator{} + + gasPrice, err := g.DenoteInUSD(tc.gasPrice, tc.nativePrice) + assert.NoError(t, err) + assert.True(t, ((*big.Int)(tc.expPrice)).Cmp(gasPrice) == 0) + }) + } +} + +func TestExecPriceEstimator_Median(t *testing.T) { + val1e18 := func(val int64) *big.Int { return new(big.Int).Mul(big.NewInt(1e18), big.NewInt(val)) } + + testCases := []struct { + name string + gasPrices []GasPrice + expMedian GasPrice + }{ + { + name: "base", + gasPrices: []GasPrice{big.NewInt(1), big.NewInt(2), big.NewInt(3)}, + expMedian: big.NewInt(2), + }, + { + name: "median 1", + gasPrices: []GasPrice{big.NewInt(1)}, + expMedian: big.NewInt(1), + }, + { + name: "median 2", + gasPrices: []GasPrice{big.NewInt(1), big.NewInt(2)}, + expMedian: big.NewInt(2), + }, + { + name: "large values", + gasPrices: []GasPrice{val1e18(5), val1e18(4), val1e18(3), val1e18(2), val1e18(1)}, + expMedian: val1e18(3), + }, + { + name: "zeros", + gasPrices: []GasPrice{big.NewInt(0), big.NewInt(0), big.NewInt(0)}, + expMedian: big.NewInt(0), + }, + { + name: "unsorted even number of prices", + gasPrices: []GasPrice{big.NewInt(4), big.NewInt(2), big.NewInt(3), big.NewInt(1)}, + expMedian: big.NewInt(3), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := ExecGasPriceEstimator{} + + gasPrice, err := g.Median(tc.gasPrices) + assert.NoError(t, err) + assert.True(t, ((*big.Int)(tc.expMedian)).Cmp(gasPrice) == 0) + }) + } +} + +func TestExecPriceEstimator_Deviates(t *testing.T) { + testCases := []struct { + name string + gasPrice1 GasPrice + gasPrice2 GasPrice + deviationPPB int64 + expDeviates bool + }{ + { + name: "base", + gasPrice1: big.NewInt(100e8), + gasPrice2: big.NewInt(79e8), + deviationPPB: 2e8, + expDeviates: true, + }, + { + name: "negative difference also deviates", + gasPrice1: big.NewInt(100e8), + gasPrice2: big.NewInt(121e8), + deviationPPB: 2e8, + expDeviates: true, + }, + { + name: "larger difference deviates", + gasPrice1: big.NewInt(100e8), + gasPrice2: big.NewInt(70e8), + deviationPPB: 2e8, + expDeviates: true, + }, + { + name: "smaller difference does not deviate", + gasPrice1: big.NewInt(100e8), + gasPrice2: big.NewInt(90e8), + deviationPPB: 2e8, + expDeviates: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := ExecGasPriceEstimator{ + deviationPPB: tc.deviationPPB, + } + + deviated, err := g.Deviates(tc.gasPrice1, tc.gasPrice2) + assert.NoError(t, err) + if tc.expDeviates { + assert.True(t, deviated) + } else { + assert.False(t, deviated) + } + }) + } +} + +func TestExecPriceEstimator_EstimateMsgCostUSD(t *testing.T) { + testCases := []struct { + name string + gasPrice GasPrice + wrappedNativePrice *big.Int + msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta + expUSD *big.Int + }{ + { + name: "base", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + GasLimit: big.NewInt(100_000), + Data: []byte{}, + TokenAmounts: []internal.TokenAmount{}, + }, + }, + expUSD: big.NewInt(300_000e9), + }, + { + name: "base with data", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + GasLimit: big.NewInt(100_000), + Data: make([]byte, 1_000), + TokenAmounts: []internal.TokenAmount{}, + }, + }, + expUSD: big.NewInt(316_000e9), + }, + { + name: "base with data and tokens", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + GasLimit: big.NewInt(100_000), + Data: make([]byte, 1_000), + TokenAmounts: make([]internal.TokenAmount, 5), + }, + }, + expUSD: big.NewInt(366_000e9), + }, + { + name: "empty msg", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + GasLimit: big.NewInt(0), + Data: []byte{}, + TokenAmounts: []internal.TokenAmount{}, + }, + }, + expUSD: big.NewInt(200_000e9), + }, + { + name: "double native price", + gasPrice: big.NewInt(1e9), // 1 gwei + wrappedNativePrice: big.NewInt(2e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + GasLimit: big.NewInt(0), + Data: []byte{}, + TokenAmounts: []internal.TokenAmount{}, + }, + }, + expUSD: big.NewInt(400_000e9), + }, + { + name: "zero gas price", + gasPrice: big.NewInt(0), // 1 gwei + wrappedNativePrice: big.NewInt(1e18), // $1 + msg: internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ + EVM2EVMMessage: internal.EVM2EVMMessage{ + GasLimit: big.NewInt(0), + Data: []byte{}, + TokenAmounts: []internal.TokenAmount{}, + }, + }, + expUSD: big.NewInt(0), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + g := ExecGasPriceEstimator{} + + costUSD, err := g.EstimateMsgCostUSD(tc.gasPrice, tc.wrappedNativePrice, tc.msg) + assert.NoError(t, err) + assert.Equal(t, tc.expUSD, costUSD) + }) + } +} + +func TestExecPriceEstimator_String(t *testing.T) { + g := ExecGasPriceEstimator{} + + str := g.String(big.NewInt(1)) + assert.Equal(t, "1", str) +} diff --git a/core/services/ocr2/plugins/ccip/prices/gas_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator.go new file mode 100644 index 0000000000..2a3935b7bc --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator.go @@ -0,0 +1,101 @@ +package prices + +import ( + "context" + "math/big" + + "github.com/Masterminds/semver/v3" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" +) + +const ( + feeBoostingOverheadGas = 200_000 + // execGasPerToken is lower-bound estimation of ERC20 releaseOrMint gas cost (Mint with static minter). + // Use this in per-token gas cost calc as heuristic to simplify estimation logic. + execGasPerToken = 10_000 + // execGasPerPayloadByte is gas charged for passing each byte of `data` payload to CCIP receiver, ignores 4 gas per 0-byte rule. + // This can be a constant as it is part of EVM spec. Changes should be rare. + execGasPerPayloadByte = 16 + // evmMessageFixedBytes is byte size of fixed-size fields in EVM2EVMMessage + // Updating EVM2EVMMessage involves an offchain upgrade, safe to keep this as constant in code. + evmMessageFixedBytes = 448 + evmMessageBytesPerToken = 128 // Byte size of each token transfer, consisting of 1 EVMTokenAmount and 1 bytes, excl length of bytes + daMultiplierBase = int64(10000) // DA multiplier is in multiples of 0.0001, i.e. 1/daMultiplierBase + daGasPriceEncodingLength = 112 // Each gas price takes up at most GasPriceEncodingLength number of bits +) + +// GasPrice represents gas price as a single big.Int, same as gas price representation onchain. +// (multi-component gas prices are encoded into the int) +type GasPrice *big.Int + +// gasPriceEstimatorCommon is abstraction over multi-component gas prices. +type gasPriceEstimatorCommon interface { + // GetGasPrice fetches the current gas price. + GetGasPrice(ctx context.Context) (GasPrice, error) + // DenoteInUSD converts the gas price to be in units of USD. Input prices should not be nil. + DenoteInUSD(p GasPrice, wrappedNativePrice *big.Int) (GasPrice, error) + // Median finds the median gas price in slice. If gas price has multiple components, median of each individual component should be taken. Input prices should not contain nil. + Median(gasPrices []GasPrice) (GasPrice, error) + // String converts the gas price to string. + String(p GasPrice) string +} + +// GasPriceEstimatorCommit provides gasPriceEstimatorCommon + features needed in commit plugin, e.g. price deviation check. +// +//go:generate mockery --quiet --name GasPriceEstimatorCommit --output . --filename gas_price_estimator_commit_mock.go --inpackage --case=underscore +type GasPriceEstimatorCommit interface { + gasPriceEstimatorCommon + // Deviates checks if p1 gas price diffs from p2 by deviation options. Input prices should not be nil. + Deviates(p1 GasPrice, p2 GasPrice) (bool, error) +} + +// GasPriceEstimatorExec provides gasPriceEstimatorCommon + features needed in exec plugin, e.g. message cost estimation. +// +//go:generate mockery --quiet --name GasPriceEstimatorExec --output . --filename gas_price_estimator_exec_mock.go --inpackage --case=underscore +type GasPriceEstimatorExec interface { + gasPriceEstimatorCommon + // EstimateMsgCostUSD estimates the costs for msg execution, and converts to USD value scaled by 1e18 (e.g. 5$ = 5e18). + EstimateMsgCostUSD(p GasPrice, wrappedNativePrice *big.Int, msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) +} + +// GasPriceEstimator provides complete gas price estimator functions. +// +//go:generate mockery --quiet --name GasPriceEstimator --output . --filename gas_price_estimator_mock.go --inpackage --case=underscore +type GasPriceEstimator interface { + GasPriceEstimatorCommit + GasPriceEstimatorExec +} + +func NewGasPriceEstimatorForCommitPlugin( + commitStoreVersion semver.Version, + estimator gas.EvmFeeEstimator, + maxExecGasPrice *big.Int, + daDeviationPPB int64, + execDeviationPPB int64, +) (GasPriceEstimatorCommit, error) { + execEstimator := ExecGasPriceEstimator{ + estimator: estimator, + maxGasPrice: maxExecGasPrice, + deviationPPB: execDeviationPPB, + } + + switch commitStoreVersion.String() { + case "1.0.0", "1.1.0": + return execEstimator, nil + case "1.2.0": + return DAGasPriceEstimator{ + execEstimator: execEstimator, + l1Oracle: estimator.L1Oracle(), + priceEncodingLength: daGasPriceEncodingLength, + daDeviationPPB: daDeviationPPB, + daOverheadGas: 0, + gasPerDAByte: 0, + daMultiplier: 0, + }, nil + default: + return nil, errors.Errorf("Invalid commitStore version: %s", commitStoreVersion) + } +} diff --git a/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_commit_mock.go b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_commit_mock.go new file mode 100644 index 0000000000..86d3d3c27c --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_commit_mock.go @@ -0,0 +1,146 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package prices + +import ( + context "context" + big "math/big" + + mock "github.com/stretchr/testify/mock" +) + +// MockGasPriceEstimatorCommit is an autogenerated mock type for the GasPriceEstimatorCommit type +type MockGasPriceEstimatorCommit struct { + mock.Mock +} + +// DenoteInUSD provides a mock function with given fields: p, wrappedNativePrice +func (_m *MockGasPriceEstimatorCommit) DenoteInUSD(p GasPrice, wrappedNativePrice *big.Int) (GasPrice, error) { + ret := _m.Called(p, wrappedNativePrice) + + var r0 GasPrice + var r1 error + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int) (GasPrice, error)); ok { + return rf(p, wrappedNativePrice) + } + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int) GasPrice); ok { + r0 = rf(p, wrappedNativePrice) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(GasPrice) + } + } + + if rf, ok := ret.Get(1).(func(GasPrice, *big.Int) error); ok { + r1 = rf(p, wrappedNativePrice) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Deviates provides a mock function with given fields: p1, p2 +func (_m *MockGasPriceEstimatorCommit) Deviates(p1 GasPrice, p2 GasPrice) (bool, error) { + ret := _m.Called(p1, p2) + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(GasPrice, GasPrice) (bool, error)); ok { + return rf(p1, p2) + } + if rf, ok := ret.Get(0).(func(GasPrice, GasPrice) bool); ok { + r0 = rf(p1, p2) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(GasPrice, GasPrice) error); ok { + r1 = rf(p1, p2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetGasPrice provides a mock function with given fields: ctx +func (_m *MockGasPriceEstimatorCommit) GetGasPrice(ctx context.Context) (GasPrice, error) { + ret := _m.Called(ctx) + + var r0 GasPrice + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (GasPrice, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) GasPrice); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(GasPrice) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Median provides a mock function with given fields: gasPrices +func (_m *MockGasPriceEstimatorCommit) Median(gasPrices []GasPrice) (GasPrice, error) { + ret := _m.Called(gasPrices) + + var r0 GasPrice + var r1 error + if rf, ok := ret.Get(0).(func([]GasPrice) (GasPrice, error)); ok { + return rf(gasPrices) + } + if rf, ok := ret.Get(0).(func([]GasPrice) GasPrice); ok { + r0 = rf(gasPrices) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(GasPrice) + } + } + + if rf, ok := ret.Get(1).(func([]GasPrice) error); ok { + r1 = rf(gasPrices) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// String provides a mock function with given fields: p +func (_m *MockGasPriceEstimatorCommit) String(p GasPrice) string { + ret := _m.Called(p) + + var r0 string + if rf, ok := ret.Get(0).(func(GasPrice) string); ok { + r0 = rf(p) + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +type mockConstructorTestingTNewMockGasPriceEstimatorCommit interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockGasPriceEstimatorCommit creates a new instance of MockGasPriceEstimatorCommit. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockGasPriceEstimatorCommit(t mockConstructorTestingTNewMockGasPriceEstimatorCommit) *MockGasPriceEstimatorCommit { + mock := &MockGasPriceEstimatorCommit{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_exec_mock.go b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_exec_mock.go new file mode 100644 index 0000000000..f1fd155da0 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_exec_mock.go @@ -0,0 +1,149 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package prices + +import ( + context "context" + big "math/big" + + internal "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + mock "github.com/stretchr/testify/mock" +) + +// MockGasPriceEstimatorExec is an autogenerated mock type for the GasPriceEstimatorExec type +type MockGasPriceEstimatorExec struct { + mock.Mock +} + +// DenoteInUSD provides a mock function with given fields: p, wrappedNativePrice +func (_m *MockGasPriceEstimatorExec) DenoteInUSD(p GasPrice, wrappedNativePrice *big.Int) (GasPrice, error) { + ret := _m.Called(p, wrappedNativePrice) + + var r0 GasPrice + var r1 error + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int) (GasPrice, error)); ok { + return rf(p, wrappedNativePrice) + } + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int) GasPrice); ok { + r0 = rf(p, wrappedNativePrice) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(GasPrice) + } + } + + if rf, ok := ret.Get(1).(func(GasPrice, *big.Int) error); ok { + r1 = rf(p, wrappedNativePrice) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EstimateMsgCostUSD provides a mock function with given fields: p, wrappedNativePrice, msg +func (_m *MockGasPriceEstimatorExec) EstimateMsgCostUSD(p GasPrice, wrappedNativePrice *big.Int, msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) { + ret := _m.Called(p, wrappedNativePrice, msg) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int, internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error)); ok { + return rf(p, wrappedNativePrice, msg) + } + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int, internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) *big.Int); ok { + r0 = rf(p, wrappedNativePrice, msg) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(GasPrice, *big.Int, internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) error); ok { + r1 = rf(p, wrappedNativePrice, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetGasPrice provides a mock function with given fields: ctx +func (_m *MockGasPriceEstimatorExec) GetGasPrice(ctx context.Context) (GasPrice, error) { + ret := _m.Called(ctx) + + var r0 GasPrice + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (GasPrice, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) GasPrice); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(GasPrice) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Median provides a mock function with given fields: gasPrices +func (_m *MockGasPriceEstimatorExec) Median(gasPrices []GasPrice) (GasPrice, error) { + ret := _m.Called(gasPrices) + + var r0 GasPrice + var r1 error + if rf, ok := ret.Get(0).(func([]GasPrice) (GasPrice, error)); ok { + return rf(gasPrices) + } + if rf, ok := ret.Get(0).(func([]GasPrice) GasPrice); ok { + r0 = rf(gasPrices) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(GasPrice) + } + } + + if rf, ok := ret.Get(1).(func([]GasPrice) error); ok { + r1 = rf(gasPrices) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// String provides a mock function with given fields: p +func (_m *MockGasPriceEstimatorExec) String(p GasPrice) string { + ret := _m.Called(p) + + var r0 string + if rf, ok := ret.Get(0).(func(GasPrice) string); ok { + r0 = rf(p) + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +type mockConstructorTestingTNewMockGasPriceEstimatorExec interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockGasPriceEstimatorExec creates a new instance of MockGasPriceEstimatorExec. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockGasPriceEstimatorExec(t mockConstructorTestingTNewMockGasPriceEstimatorExec) *MockGasPriceEstimatorExec { + mock := &MockGasPriceEstimatorExec{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_mock.go b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_mock.go new file mode 100644 index 0000000000..8ff5e29cd3 --- /dev/null +++ b/core/services/ocr2/plugins/ccip/prices/gas_price_estimator_mock.go @@ -0,0 +1,173 @@ +// Code generated by mockery v2.28.1. DO NOT EDIT. + +package prices + +import ( + context "context" + big "math/big" + + internal "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + mock "github.com/stretchr/testify/mock" +) + +// MockGasPriceEstimator is an autogenerated mock type for the GasPriceEstimator type +type MockGasPriceEstimator struct { + mock.Mock +} + +// DenoteInUSD provides a mock function with given fields: p, wrappedNativePrice +func (_m *MockGasPriceEstimator) DenoteInUSD(p GasPrice, wrappedNativePrice *big.Int) (GasPrice, error) { + ret := _m.Called(p, wrappedNativePrice) + + var r0 GasPrice + var r1 error + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int) (GasPrice, error)); ok { + return rf(p, wrappedNativePrice) + } + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int) GasPrice); ok { + r0 = rf(p, wrappedNativePrice) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(GasPrice) + } + } + + if rf, ok := ret.Get(1).(func(GasPrice, *big.Int) error); ok { + r1 = rf(p, wrappedNativePrice) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Deviates provides a mock function with given fields: p1, p2 +func (_m *MockGasPriceEstimator) Deviates(p1 GasPrice, p2 GasPrice) (bool, error) { + ret := _m.Called(p1, p2) + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(GasPrice, GasPrice) (bool, error)); ok { + return rf(p1, p2) + } + if rf, ok := ret.Get(0).(func(GasPrice, GasPrice) bool); ok { + r0 = rf(p1, p2) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(GasPrice, GasPrice) error); ok { + r1 = rf(p1, p2) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// EstimateMsgCostUSD provides a mock function with given fields: p, wrappedNativePrice, msg +func (_m *MockGasPriceEstimator) EstimateMsgCostUSD(p GasPrice, wrappedNativePrice *big.Int, msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) { + ret := _m.Called(p, wrappedNativePrice, msg) + + var r0 *big.Int + var r1 error + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int, internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error)); ok { + return rf(p, wrappedNativePrice, msg) + } + if rf, ok := ret.Get(0).(func(GasPrice, *big.Int, internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) *big.Int); ok { + r0 = rf(p, wrappedNativePrice, msg) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + if rf, ok := ret.Get(1).(func(GasPrice, *big.Int, internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) error); ok { + r1 = rf(p, wrappedNativePrice, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetGasPrice provides a mock function with given fields: ctx +func (_m *MockGasPriceEstimator) GetGasPrice(ctx context.Context) (GasPrice, error) { + ret := _m.Called(ctx) + + var r0 GasPrice + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (GasPrice, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) GasPrice); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(GasPrice) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Median provides a mock function with given fields: gasPrices +func (_m *MockGasPriceEstimator) Median(gasPrices []GasPrice) (GasPrice, error) { + ret := _m.Called(gasPrices) + + var r0 GasPrice + var r1 error + if rf, ok := ret.Get(0).(func([]GasPrice) (GasPrice, error)); ok { + return rf(gasPrices) + } + if rf, ok := ret.Get(0).(func([]GasPrice) GasPrice); ok { + r0 = rf(gasPrices) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(GasPrice) + } + } + + if rf, ok := ret.Get(1).(func([]GasPrice) error); ok { + r1 = rf(gasPrices) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// String provides a mock function with given fields: p +func (_m *MockGasPriceEstimator) String(p GasPrice) string { + ret := _m.Called(p) + + var r0 string + if rf, ok := ret.Get(0).(func(GasPrice) string); ok { + r0 = rf(p) + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +type mockConstructorTestingTNewMockGasPriceEstimator interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockGasPriceEstimator creates a new instance of MockGasPriceEstimator. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockGasPriceEstimator(t mockConstructorTestingTNewMockGasPriceEstimator) *MockGasPriceEstimator { + mock := &MockGasPriceEstimator{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go index 092650d0d2..37aff4002c 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/ccip_contracts.go @@ -38,8 +38,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/burn_mint_erc677" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/hashlib" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/merklemulti" + "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" ) @@ -66,6 +68,99 @@ var ( DestChainSelector = uint64(3379446385462418246) ) +// Backwards compat, in principle these statuses are version dependent +// TODO: Adjust integration tests to be version agnostic using readers +var ( + ExecutionStateSuccess = MessageExecutionState(ccipdata.ExecutionStateSuccess) + ExecutionStateFailure = MessageExecutionState(ccipdata.ExecutionStateFailure) +) + +type MessageExecutionState ccipdata.MessageExecutionState +type CommitOffchainConfig struct { + ccipdata.CommitOffchainConfigV1_2_0 +} + +func NewCommitOffchainConfig(SourceFinalityDepth uint32, + DestFinalityDepth uint32, + GasPriceHeartBeat models.Duration, + DAGasPriceDeviationPPB uint32, + ExecGasPriceDeviationPPB uint32, + TokenPriceHeartBeat models.Duration, + TokenPriceDeviationPPB uint32, + MaxGasPrice uint64, + InflightCacheExpiry models.Duration) CommitOffchainConfig { + return CommitOffchainConfig{ccipdata.CommitOffchainConfigV1_2_0{ + SourceFinalityDepth: SourceFinalityDepth, + DestFinalityDepth: DestFinalityDepth, + GasPriceHeartBeat: GasPriceHeartBeat, + DAGasPriceDeviationPPB: DAGasPriceDeviationPPB, + ExecGasPriceDeviationPPB: ExecGasPriceDeviationPPB, + TokenPriceHeartBeat: TokenPriceHeartBeat, + TokenPriceDeviationPPB: TokenPriceDeviationPPB, + MaxGasPrice: MaxGasPrice, + InflightCacheExpiry: InflightCacheExpiry, + }} +} + +type CommitOnchainConfig struct { + ccipdata.CommitOnchainConfig +} + +func NewCommitOnchainConfig( + PriceRegistry common.Address, +) CommitOnchainConfig { + return CommitOnchainConfig{ccipdata.CommitOnchainConfig{ + PriceRegistry: PriceRegistry, + }} +} + +type ExecOnchainConfig struct { + ccipdata.ExecOnchainConfigV1_0_0 +} + +func NewExecOnchainConfig( + PermissionLessExecutionThresholdSeconds uint32, + Router common.Address, + PriceRegistry common.Address, + MaxTokensLength uint16, + MaxDataSize uint32, +) ExecOnchainConfig { + return ExecOnchainConfig{ccipdata.ExecOnchainConfigV1_0_0{ + PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, + Router: Router, + PriceRegistry: PriceRegistry, + MaxTokensLength: MaxTokensLength, + MaxDataSize: MaxDataSize, + }} +} + +type ExecOffchainConfig struct { + ccipdata.ExecOffchainConfig +} + +func NewExecOffchainConfig( + SourceFinalityDepth uint32, + DestOptimisticConfirmations uint32, + DestFinalityDepth uint32, + BatchGasLimit uint32, + RelativeBoostPerWaitHour float64, + MaxGasPrice uint64, + InflightCacheExpiry models.Duration, + RootSnoozeTime models.Duration, +) ExecOffchainConfig { + return ExecOffchainConfig{ccipdata.ExecOffchainConfig{ + SourceFinalityDepth: SourceFinalityDepth, + DestOptimisticConfirmations: DestOptimisticConfirmations, + DestFinalityDepth: DestFinalityDepth, + BatchGasLimit: BatchGasLimit, + RelativeBoostPerWaitHour: RelativeBoostPerWaitHour, + MaxGasPrice: MaxGasPrice, + InflightCacheExpiry: InflightCacheExpiry, + RootSnoozeTime: RootSnoozeTime, + }} + +} + type MaybeRevertReceiver struct { Receiver *maybe_revert_message_receiver.MaybeRevertMessageReceiver Strict bool @@ -248,28 +343,26 @@ func (c *CCIPContracts) DeployNewOnRamp(t *testing.T) { }, []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ { - Token: c.Source.LinkToken.Address(), - NetworkFeeUSD: 1_00, - MinTokenTransferFeeUSD: 1_00, - MaxTokenTransferFeeUSD: 5000_00, - GasMultiplier: 1e18, - PremiumMultiplier: 9e17, - Enabled: true, + Token: c.Source.LinkToken.Address(), + NetworkFeeUSD: 1_00, + GasMultiplier: 1e18, + PremiumMultiplier: 9e17, + Enabled: true, }, { - Token: c.Source.WrappedNative.Address(), - NetworkFeeUSD: 1_00, - MinTokenTransferFeeUSD: 1_00, - MaxTokenTransferFeeUSD: 5000_00, - GasMultiplier: 1e18, - PremiumMultiplier: 1e18, - Enabled: true, + Token: c.Source.WrappedNative.Address(), + NetworkFeeUSD: 1_00, + GasMultiplier: 1e18, + PremiumMultiplier: 1e18, + Enabled: true, }, }, []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ { Token: c.Source.LinkToken.Address(), - Ratio: 5_0, // 5 bps + MinFeeUSD: 50, // $0.5 + MaxFeeUSD: 1_000_000_00, // $ 1 million + Ratio: 5_0, // 5 bps DestGasOverhead: 34_000, DestBytesOverhead: 0, }, @@ -361,8 +454,12 @@ func (c *CCIPContracts) DeployNewPriceRegistry(t *testing.T) { UsdPerToken: big.NewInt(1e18), // 1usd }, }, - DestChainSelector: c.Source.ChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: c.Source.ChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, } _, err = c.Dest.PriceRegistry.UpdatePrices(c.Dest.User, priceUpdates) require.NoError(t, err) @@ -613,8 +710,12 @@ func (c *CCIPContracts) SetupLockAndMintTokenPool( UsdPerToken: big.NewInt(1e18), // 1usd }, }, - DestChainSelector: c.Dest.ChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9, + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: c.Dest.ChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9, + }, + }, }) if err != nil { return [20]byte{}, nil, err @@ -644,8 +745,12 @@ func (c *CCIPContracts) SetupLockAndMintTokenPool( UsdPerToken: big.NewInt(5), }, }, - DestChainSelector: c.Source.ChainSelector, - UsdPerUnitGas: big.NewInt(0), + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: c.Source.ChainSelector, + UsdPerUnitGas: big.NewInt(0), + }, + }, }) if err != nil { return [20]byte{}, nil, err @@ -670,8 +775,12 @@ func (c *CCIPContracts) SetupLockAndMintTokenPool( UsdPerToken: big.NewInt(5), }, }, - DestChainSelector: 0, - UsdPerUnitGas: big.NewInt(0), + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: 0, + UsdPerUnitGas: big.NewInt(0), + }, + }, }) if err != nil { return [20]byte{}, nil, err @@ -884,8 +993,12 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh UsdPerToken: new(big.Int).Mul(big.NewInt(1e18), big.NewInt(2)), // TODO make this 2000USD and once we figure out the fee and exec cost discrepancy }, }, - DestChainSelector: destChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: destChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, } _, err = srcPriceRegistry.UpdatePrices(sourceUser, prices) @@ -932,28 +1045,26 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh }, []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ { - Token: sourceLinkTokenAddress, - NetworkFeeUSD: 1_00, - MinTokenTransferFeeUSD: 1_00, - MaxTokenTransferFeeUSD: 5000_00, - GasMultiplier: 1e18, - PremiumMultiplier: 9e17, - Enabled: true, + Token: sourceLinkTokenAddress, + NetworkFeeUSD: 1_00, + GasMultiplier: 1e18, + PremiumMultiplier: 9e17, + Enabled: true, }, { - Token: sourceWeth9addr, - NetworkFeeUSD: 1_00, - MinTokenTransferFeeUSD: 1_00, - MaxTokenTransferFeeUSD: 5000_00, - GasMultiplier: 1e18, - PremiumMultiplier: 1e18, - Enabled: true, + Token: sourceWeth9addr, + NetworkFeeUSD: 1_00, + GasMultiplier: 1e18, + PremiumMultiplier: 1e18, + Enabled: true, }, }, []evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ { Token: sourceLinkTokenAddress, - Ratio: 5_0, // 5 bps + MinFeeUSD: 50, // $0.5 + MaxFeeUSD: 1_000_000_00, // $ 1 million + Ratio: 5_0, // 5 bps DestGasOverhead: 34_000, DestBytesOverhead: 0, }, @@ -1024,8 +1135,12 @@ func SetupCCIPContracts(t *testing.T, sourceChainID, sourceChainSelector, destCh {SourceToken: destCustomTokenAddress, UsdPerToken: big.NewInt(5e18)}, // 5usd {SourceToken: destWeth9addr, UsdPerToken: big.NewInt(2e18)}, // 2usd }, - DestChainSelector: sourceChainSelector, - UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + GasPriceUpdates: []price_registry.InternalGasPriceUpdate{ + { + DestChainSelector: sourceChainSelector, + UsdPerUnitGas: big.NewInt(2000e9), // $2000 per eth * 1gwei = 2000e9 + }, + }, } _, err = destPriceRegistry.UpdatePrices(destUser, destPrices) @@ -1168,7 +1283,7 @@ func (c *CCIPContracts) SendRequest(t *testing.T, msg router.ClientEVM2AnyMessag return tx } -func (c *CCIPContracts) AssertExecState(t *testing.T, log logpoller.Log, state abihelpers.MessageExecutionState, offRampOpts ...common.Address) { +func (c *CCIPContracts) AssertExecState(t *testing.T, log logpoller.Log, state MessageExecutionState, offRampOpts ...common.Address) { var offRamp *evm_2_evm_offramp.EVM2EVMOffRamp var err error if len(offRampOpts) > 0 { @@ -1180,7 +1295,7 @@ func (c *CCIPContracts) AssertExecState(t *testing.T, log logpoller.Log, state a } executionStateChanged, err := offRamp.ParseExecutionStateChanged(log.ToGethLog()) require.NoError(t, err) - if abihelpers.MessageExecutionState(executionStateChanged.State) != state { + if MessageExecutionState(executionStateChanged.State) != state { t.Log("Execution failed") t.Fail() } @@ -1358,7 +1473,7 @@ func (args *ManualExecArgs) execute(report *commit_store.CommitStoreCommitReport seqNr := args.seqNr // Build a merkle tree for the report mctx := hashlib.NewKeccakCtx() - leafHasher := hashlib.NewLeafHasher(args.SourceChainID, args.DestChainID, common.HexToAddress(args.OnRamp), mctx) + leafHasher := ccipdata.NewLeafHasherV1_2_0(args.SourceChainID, args.DestChainID, common.HexToAddress(args.OnRamp), mctx, &evm_2_evm_onramp.EVM2EVMOnRamp{}) onRampContract, err := evm_2_evm_onramp.NewEVM2EVMOnRamp(common.HexToAddress(args.OnRamp), args.SourceChain) if err != nil { return nil, err @@ -1385,7 +1500,7 @@ func (args *ManualExecArgs) execute(report *commit_store.CommitStoreCommitReport leaves = append(leaves, hash) if sendRequestedIterator.Event.Message.SequenceNumber == seqNr { fmt.Printf("Found proving %d %+v\n", curr, sendRequestedIterator.Event.Message) - msg, err2 := abihelpers.DecodeOffRampMessage(sendRequestedIterator.Event.Raw.Data) + msg, err2 := ccipdata.DecodeOffRampMessageV1_2_0(sendRequestedIterator.Event.Raw.Data) if err2 != nil { return nil, err2 } @@ -1475,13 +1590,3 @@ func GetBalance(t *testing.T, chain bind.ContractBackend, tokenAddr common.Addre require.NoError(t, err) return bal } - -func GenerateCCIPSendLog(t *testing.T, message evm_2_evm_onramp.InternalEVM2EVMMessage) types.Log { - pack, err := abihelpers.MessageArgs.Pack(message) - require.NoError(t, err) - - return types.Log{ - Topics: []common.Hash{abihelpers.EventSignatures.SendRequested}, - Data: pack, - } -} diff --git a/core/services/ocr2/plugins/ccip/testhelpers/commitstore.go b/core/services/ocr2/plugins/ccip/testhelpers/commitstore.go index b41104c44f..726eae2312 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/commitstore.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/commitstore.go @@ -26,6 +26,7 @@ type FakeCommitStore struct { func NewFakeCommitStore(t *testing.T, nextSeqNum uint64) (*FakeCommitStore, common.Address) { addr := utils.RandomAddress() + //mockCommitStore := mock_contracts.NewCommitStoreInterface(t) mockCommitStore := mock_contracts.NewCommitStoreInterface(t) mockCommitStore.On("Address").Return(addr).Maybe() diff --git a/core/services/ocr2/plugins/ccip/testhelpers/config.go b/core/services/ocr2/plugins/ccip/testhelpers/config.go index 85569a77ae..baa4d8e5aa 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/config.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/config.go @@ -10,13 +10,14 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) -const PermissionLessExecutionThresholdSeconds = 20 * 60 +var PermissionLessExecutionThresholdSeconds = uint32(FirstBlockAge.Seconds()) func (c *CCIPContracts) CreateDefaultCommitOnchainConfig(t *testing.T) []byte { - config, err := abihelpers.EncodeAbiStruct(ccipconfig.CommitOnchainConfig{ + config, err := abihelpers.EncodeAbiStruct(ccipdata.CommitOnchainConfig{ PriceRegistry: c.Dest.PriceRegistry.Address(), }) require.NoError(t, err) @@ -28,20 +29,23 @@ func (c *CCIPContracts) CreateDefaultCommitOffchainConfig(t *testing.T) []byte { } func (c *CCIPContracts) createCommitOffchainConfig(t *testing.T, feeUpdateHearBeat time.Duration, inflightCacheExpiry time.Duration) []byte { - config, err := ccipconfig.EncodeOffchainConfig(ccipconfig.CommitOffchainConfig{ - SourceFinalityDepth: 1, - DestFinalityDepth: 1, - FeeUpdateHeartBeat: models.MustMakeDuration(feeUpdateHearBeat), - FeeUpdateDeviationPPB: 1, - MaxGasPrice: 200e9, - InflightCacheExpiry: models.MustMakeDuration(inflightCacheExpiry), + config, err := ccipconfig.EncodeOffchainConfig(ccipdata.CommitOffchainConfigV1_2_0{ + SourceFinalityDepth: 1, + DestFinalityDepth: 1, + GasPriceHeartBeat: models.MustMakeDuration(feeUpdateHearBeat), + DAGasPriceDeviationPPB: 1, + ExecGasPriceDeviationPPB: 1, + TokenPriceHeartBeat: models.MustMakeDuration(feeUpdateHearBeat), + TokenPriceDeviationPPB: 1, + MaxGasPrice: 200e9, + InflightCacheExpiry: models.MustMakeDuration(inflightCacheExpiry), }) require.NoError(t, err) return config } func (c *CCIPContracts) CreateDefaultExecOnchainConfig(t *testing.T) []byte { - config, err := abihelpers.EncodeAbiStruct(ccipconfig.ExecOnchainConfig{ + config, err := abihelpers.EncodeAbiStruct(ccipdata.ExecOnchainConfigV1_0_0{ PermissionLessExecutionThresholdSeconds: PermissionLessExecutionThresholdSeconds, Router: c.Dest.Router.Address(), PriceRegistry: c.Dest.PriceRegistry.Address(), @@ -57,7 +61,7 @@ func (c *CCIPContracts) CreateDefaultExecOffchainConfig(t *testing.T) []byte { } func (c *CCIPContracts) createExecOffchainConfig(t *testing.T, inflightCacheExpiry time.Duration, rootSnoozeTime time.Duration) []byte { - config, err := ccipconfig.EncodeOffchainConfig(ccipconfig.ExecOffchainConfig{ + config, err := ccipconfig.EncodeOffchainConfig(ccipdata.ExecOffchainConfig{ SourceFinalityDepth: 1, DestOptimisticConfirmations: 1, DestFinalityDepth: 1, diff --git a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go index 1b92a30996..a52b7c0c80 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/integration/chainlink.go @@ -28,6 +28,7 @@ import ( "github.com/smartcontractkit/chainlink-relay/pkg/loop" ctfClient "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" v2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -46,7 +47,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/chaintype" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/ocr2key" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/validate" "github.com/smartcontractkit/chainlink/v2/core/services/ocrbootstrap" @@ -83,7 +84,7 @@ func (node *Node) EventuallyNodeUsesUpdatedPriceRegistry(t *testing.T, ccipContr ccipContracts.Source.Chain.Commit() ccipContracts.Dest.Chain.Commit() log, err := c.LogPoller().LatestLogByEventSigWithConfs( - abihelpers.EventSignatures.UsdPerUnitGasUpdated, + ccipdata.UsdPerUnitGasUpdatedV1_0_0, ccipContracts.Dest.PriceRegistry.Address(), 0, pg.WithParentCtx(testutils.Context(t)), @@ -97,7 +98,7 @@ func (node *Node) EventuallyNodeUsesUpdatedPriceRegistry(t *testing.T, ccipContr return log } -func (node *Node) EventuallyNodeUsesNewCommitConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, commitCfg ccipconfig.CommitOnchainConfig) logpoller.Log { +func (node *Node) EventuallyNodeUsesNewCommitConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, commitCfg ccipdata.CommitOnchainConfig) logpoller.Log { c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) require.NoError(t, err) var log logpoller.Log @@ -111,7 +112,7 @@ func (node *Node) EventuallyNodeUsesNewCommitConfig(t *testing.T, ccipContracts pg.WithParentCtx(testutils.Context(t)), ) require.NoError(t, err) - var latestCfg ccipconfig.CommitOnchainConfig + var latestCfg ccipdata.CommitOnchainConfig if log != nil { latestCfg, err = DecodeCommitOnChainConfig(log.Data) require.NoError(t, err) @@ -122,7 +123,7 @@ func (node *Node) EventuallyNodeUsesNewCommitConfig(t *testing.T, ccipContracts return log } -func (node *Node) EventuallyNodeUsesNewExecConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, execCfg ccipconfig.ExecOnchainConfig) logpoller.Log { +func (node *Node) EventuallyNodeUsesNewExecConfig(t *testing.T, ccipContracts CCIPIntegrationTestHarness, execCfg ccipdata.ExecOnchainConfigV1_0_0) logpoller.Log { c, err := node.App.GetRelayers().LegacyEVMChains().Get(strconv.FormatUint(ccipContracts.Dest.ChainID, 10)) require.NoError(t, err) var log logpoller.Log @@ -136,7 +137,7 @@ func (node *Node) EventuallyNodeUsesNewExecConfig(t *testing.T, ccipContracts CC pg.WithParentCtx(testutils.Context(t)), ) require.NoError(t, err) - var latestCfg ccipconfig.ExecOnchainConfig + var latestCfg ccipdata.ExecOnchainConfigV1_0_0 if log != nil { latestCfg, err = DecodeExecOnChainConfig(log.Data) require.NoError(t, err) @@ -155,9 +156,9 @@ func (node *Node) EventuallyHasReqSeqNum(t *testing.T, ccipContracts *CCIPIntegr ccipContracts.Source.Chain.Commit() ccipContracts.Dest.Chain.Commit() lgs, err := c.LogPoller().LogsDataWordRange( - abihelpers.EventSignatures.SendRequested, + ccipdata.CCIPSendRequestEventSigV1_2_0, onRamp, - abihelpers.EventSignatures.SendRequestedSequenceNumberWord, + ccipdata.CCIPSendRequestSeqNumIndexV1_2_0, abihelpers.EvmWord(uint64(seqNum)), abihelpers.EvmWord(uint64(seqNum)), 1, @@ -182,9 +183,9 @@ func (node *Node) EventuallyHasExecutedSeqNums(t *testing.T, ccipContracts *CCIP ccipContracts.Source.Chain.Commit() ccipContracts.Dest.Chain.Commit() lgs, err := c.LogPoller().IndexedLogsTopicRange( - abihelpers.EventSignatures.ExecutionStateChanged, + ccipdata.ExecutionStateChangedEventV1_0_0, offRamp, - abihelpers.EventSignatures.ExecutionStateChangedSequenceNumberIndex, + ccipdata.ExecutionStateChangedSeqNrV1_0_0, abihelpers.EvmWord(uint64(minSeqNum)), abihelpers.EvmWord(uint64(maxSeqNum)), 1, @@ -210,9 +211,9 @@ func (node *Node) ConsistentlySeqNumHasNotBeenExecuted(t *testing.T, ccipContrac ccipContracts.Source.Chain.Commit() ccipContracts.Dest.Chain.Commit() lgs, err := c.LogPoller().IndexedLogsTopicRange( - abihelpers.EventSignatures.ExecutionStateChanged, + ccipdata.ExecutionStateChangedEventV1_0_0, offRamp, - abihelpers.EventSignatures.ExecutionStateChangedSequenceNumberIndex, + ccipdata.ExecutionStateChangedSeqNrV1_0_0, abihelpers.EvmWord(uint64(seqNum)), abihelpers.EvmWord(uint64(seqNum)), 1, @@ -274,10 +275,12 @@ func setupNodeCCIP( } c.Log.Level = &loglevel c.Feature.CCIP = &trueRef + c.Feature.UICSAKeys = &trueRef c.OCR.Enabled = &falseRef c.OCR.DefaultTransactionQueueDepth = pointer.Uint32(200) c.OCR2.Enabled = &trueRef c.Feature.LogPoller = &trueRef + c.P2P.V1.Enabled = &falseRef c.P2P.V2.Enabled = &trueRef c.P2P.V2.DeltaDial = models.MustNewDuration(500 * time.Millisecond) c.P2P.V2.DeltaReconcile = models.MustNewDuration(5 * time.Second) @@ -317,7 +320,7 @@ func setupNodeCCIP( } mailMon := utils.NewMailboxMonitor("CCIP") evmOpts := chainlink.EVMFactoryConfig{ - RelayerConfig: &evm.RelayerConfig{ + ChainOpts: evm.ChainOpts{ AppConfig: config, EventBroadcaster: eventBroadcaster, GenEthClient: func(chainID *big.Int) client.Client { @@ -330,14 +333,13 @@ func setupNodeCCIP( return nil }, MailMon: mailMon, + DB: db, }, CSAETHKeystore: simEthKeyStore, } loopRegistry := plugins.NewLoopRegistry(lggr.Named("LoopRegistry")) relayerFactory := chainlink.RelayerFactory{ Logger: lggr, - DB: db, - QConfig: config.Database(), LoopRegistry: loopRegistry, GRPCOpts: loop.GRPCOpts{}, } @@ -358,13 +360,12 @@ func setupNodeCCIP( RelayerChainInteroperators: relayChainInterops, Logger: lggr, ExternalInitiatorManager: nil, - CloseLogger: func() error { - return nil - }, - UnrestrictedHTTPClient: &http.Client{}, - RestrictedHTTPClient: &http.Client{}, - AuditLogger: audit.NoopLogger, - MailMon: mailMon, + CloseLogger: lggr.Sync, + UnrestrictedHTTPClient: &http.Client{}, + RestrictedHTTPClient: &http.Client{}, + AuditLogger: audit.NoopLogger, + MailMon: mailMon, + LoopRegistry: plugins.NewLoopRegistry(lggr), }) require.NoError(t, err) require.NoError(t, app.GetKeyStore().Unlock("password")) @@ -539,7 +540,7 @@ func (c *CCIPIntegrationTestHarness) EventuallyExecutionStateChangedToSuccess(t it, err := offRamp.FilterExecutionStateChanged(&bind.FilterOpts{Start: blockNum}, seqNum, [][32]byte{}) require.NoError(t, err) for it.Next() { - if abihelpers.MessageExecutionState(it.Event.State) == abihelpers.ExecutionStateSuccess { + if ccipdata.MessageExecutionState(it.Event.State) == ccipdata.ExecutionStateSuccess { t.Logf("ExecutionStateChanged event found for seqNum %d", it.Event.SequenceNumber) return true } @@ -705,28 +706,28 @@ func (c *CCIPIntegrationTestHarness) SetUpNodesAndJobs(t *testing.T, pricePipeli return jobParams } -func DecodeCommitOnChainConfig(encoded []byte) (ccipconfig.CommitOnchainConfig, error) { - var onchainConfig ccipconfig.CommitOnchainConfig +func DecodeCommitOnChainConfig(encoded []byte) (ccipdata.CommitOnchainConfig, error) { + var onchainConfig ccipdata.CommitOnchainConfig unpacked, err := abihelpers.DecodeOCR2Config(encoded) if err != nil { return onchainConfig, err } onChainCfg := unpacked.OnchainConfig - onchainConfig, err = abihelpers.DecodeAbiStruct[ccipconfig.CommitOnchainConfig](onChainCfg) + onchainConfig, err = abihelpers.DecodeAbiStruct[ccipdata.CommitOnchainConfig](onChainCfg) if err != nil { return onchainConfig, err } return onchainConfig, nil } -func DecodeExecOnChainConfig(encoded []byte) (ccipconfig.ExecOnchainConfig, error) { - var onchainConfig ccipconfig.ExecOnchainConfig +func DecodeExecOnChainConfig(encoded []byte) (ccipdata.ExecOnchainConfigV1_0_0, error) { + var onchainConfig ccipdata.ExecOnchainConfigV1_0_0 unpacked, err := abihelpers.DecodeOCR2Config(encoded) if err != nil { return onchainConfig, errors.Wrap(err, "failed to unpack log data") } onChainCfg := unpacked.OnchainConfig - onchainConfig, err = abihelpers.DecodeAbiStruct[ccipconfig.ExecOnchainConfig](onChainCfg) + onchainConfig, err = abihelpers.DecodeAbiStruct[ccipdata.ExecOnchainConfigV1_0_0](onChainCfg) if err != nil { return onchainConfig, err } diff --git a/core/services/ocr2/plugins/ccip/testhelpers/offramp.go b/core/services/ocr2/plugins/ccip/testhelpers/offramp.go index 16b572b5c0..4fc68db15a 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/offramp.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/offramp.go @@ -51,7 +51,13 @@ func (o *FakeOffRamp) SetSenderNonces(senderNonces map[common.Address]uint64) { } func (o *FakeOffRamp) GetPoolByDestToken(opts *bind.CallOpts, destToken common.Address) (common.Address, error) { - return getOffRampVal(o, func(o *FakeOffRamp) (common.Address, error) { return o.tokenToPool[destToken], nil }) + return getOffRampVal(o, func(o *FakeOffRamp) (common.Address, error) { + addr, exists := o.tokenToPool[destToken] + if !exists { + return common.Address{}, errors.New("not found") + } + return addr, nil + }) } func (o *FakeOffRamp) SetTokenPools(tokenToPool map[common.Address]common.Address) { @@ -92,6 +98,16 @@ func (o *FakeOffRamp) GetDestinationToken(opts *bind.CallOpts, sourceToken commo }) } +func (o *FakeOffRamp) GetDestinationTokens(opts *bind.CallOpts) ([]common.Address, error) { + return getOffRampVal(o, func(o *FakeOffRamp) ([]common.Address, error) { + tokens := make([]common.Address, 0, len(o.sourceToDestTokens)) + for _, dst := range o.sourceToDestTokens { + tokens = append(tokens, dst) + } + return tokens, nil + }) +} + func getOffRampVal[T any](o *FakeOffRamp, getter func(o *FakeOffRamp) (T, error)) (T, error) { o.mu.RLock() defer o.mu.RUnlock() diff --git a/core/services/ocr2/plugins/ccip/testhelpers/onramp.go b/core/services/ocr2/plugins/ccip/testhelpers/onramp.go index bd51b2ccd2..e7e9cabe5e 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/onramp.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/onramp.go @@ -14,6 +14,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/utils" ) +const ( + FakeOnRampVersion = "1.2.0" +) + type FakeOnRamp struct { *mock_contracts.EVM2EVMOnRampInterface @@ -32,7 +36,7 @@ func NewFakeOnRamp(t *testing.T) (*FakeOnRamp, common.Address) { } func (o *FakeOnRamp) TypeAndVersion(opts *bind.CallOpts) (string, error) { - return fmt.Sprintf("%s %s", ccipconfig.EVM2EVMOnRamp, "1.2.0"), nil + return fmt.Sprintf("%s %s", ccipconfig.EVM2EVMOnRamp, FakeOnRampVersion), nil } func (o *FakeOnRamp) SetDynamicCfg(cfg evm_2_evm_onramp.EVM2EVMOnRampDynamicConfig) { diff --git a/core/services/ocr2/plugins/ccip/testhelpers/priceregistry.go b/core/services/ocr2/plugins/ccip/testhelpers/priceregistry.go index 5b127e685c..9f0d9b5fce 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/priceregistry.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/priceregistry.go @@ -16,6 +16,7 @@ type FakePriceRegistry struct { *mock_contracts.PriceRegistryInterface tokenPrices []price_registry.InternalTimestampedPackedUint224 + feeTokens []common.Address mu sync.RWMutex } @@ -39,6 +40,14 @@ func (p *FakePriceRegistry) GetTokenPrices(opts *bind.CallOpts, tokens []common. }) } +func (p *FakePriceRegistry) SetFeeTokens(tokens []common.Address) { + setPriceRegistryVal(p, func(p *FakePriceRegistry) { p.feeTokens = tokens }) +} + +func (p *FakePriceRegistry) GetFeeTokens(opts *bind.CallOpts) ([]common.Address, error) { + return getPriceRegistryVal(p, func(p *FakePriceRegistry) ([]common.Address, error) { return p.feeTokens, nil }) +} + func getPriceRegistryVal[T any](p *FakePriceRegistry, getter func(p *FakePriceRegistry) (T, error)) (T, error) { p.mu.RLock() defer p.mu.RUnlock() diff --git a/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go b/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go index 8df31bb0f1..d1bb556093 100644 --- a/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go +++ b/core/services/ocr2/plugins/ccip/testhelpers/simulated_backend.go @@ -4,6 +4,7 @@ import ( "context" "math/big" "testing" + "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" @@ -17,6 +18,9 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore" ) +// FirstBlockAge is used to compute first block's timestamp in SimulatedBackend (time.Now() - FirstBlockAge) +const FirstBlockAge = 24 * time.Hour + func SetupChain(t *testing.T) (*backends.SimulatedBackend, *bind.TransactOpts) { key, err := crypto.GenerateKey() require.NoError(t, err) @@ -25,6 +29,15 @@ func SetupChain(t *testing.T) (*backends.SimulatedBackend, *bind.TransactOpts) { chain := backends.NewSimulatedBackend(core.GenesisAlloc{ user.From: {Balance: new(big.Int).Mul(big.NewInt(1000), big.NewInt(1e18))}}, ethconfig.Defaults.Miner.GasCeil) + // CCIP relies on block timestamps, but SimulatedBackend uses by default clock starting from 1970-01-01 + // This trick is used to move the clock closer to the current time. We set first block to be X hours ago. + // Tests create plenty of transactions so this number can't be too low, every new block mined will tick the clock, + // if you mine more than "X hours" transactions, SimulatedBackend will panic because generated timestamps will be in the future. + // IMPORTANT: Any adjustments to FirstBlockAge will automatically update PermissionLessExecutionThresholdSeconds in tests + blockTime := time.UnixMilli(int64(chain.Blockchain().CurrentHeader().Time)) + err = chain.AdjustTime(time.Since(blockTime) - FirstBlockAge) + require.NoError(t, err) + chain.Commit() return chain, user } @@ -44,7 +57,7 @@ func (ks EthKeyStoreSim) Eth() keystore.Eth { func (ks EthKeyStoreSim) SignTx(address common.Address, tx *ethtypes.Transaction, chainID *big.Int) (*ethtypes.Transaction, error) { if chainID.String() == "1000" { // A terrible hack, just for the multichain test. All simulation clients run on chainID 1337. - // We let the DestChain actually use 1337 to make sure the offchainConfig digests are properly generated. + // We let the DestChainSelector actually use 1337 to make sure the offchainConfig digests are properly generated. return ks.ETHKS.SignTx(address, tx, big.NewInt(1337)) } return ks.ETHKS.SignTx(address, tx, chainID) diff --git a/core/services/ocr2/plugins/ccip/tokendata/reader.go b/core/services/ocr2/plugins/ccip/tokendata/reader.go index ec3a2d7497..a6030c9658 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/reader.go +++ b/core/services/ocr2/plugins/ccip/tokendata/reader.go @@ -4,8 +4,8 @@ import ( "context" "errors" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) var ( @@ -18,7 +18,5 @@ var ( type Reader interface { // ReadTokenData returns the attestation bytes if ready, and throws an error if not ready. ReadTokenData(ctx context.Context, msg internal.EVM2EVMOnRampCCIPSendRequestedWithMeta) (tokenData []byte, err error) - - // GetSourceLogPollerFilters returns the filters that should be used for the source chain log poller - GetSourceLogPollerFilters() []logpoller.Filter + Close(qopts ...pg.QOpt) error } diff --git a/core/services/ocr2/plugins/ccip/tokendata/reader_mock.go b/core/services/ocr2/plugins/ccip/tokendata/reader_mock.go index 9a87fafb34..8d22f878cf 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/reader_mock.go +++ b/core/services/ocr2/plugins/ccip/tokendata/reader_mock.go @@ -5,10 +5,10 @@ package tokendata import ( context "context" - logpoller "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" internal "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" - mock "github.com/stretchr/testify/mock" + + pg "github.com/smartcontractkit/chainlink/v2/core/services/pg" ) // MockReader is an autogenerated mock type for the Reader type @@ -16,17 +16,21 @@ type MockReader struct { mock.Mock } -// GetSourceLogPollerFilters provides a mock function with given fields: -func (_m *MockReader) GetSourceLogPollerFilters() []logpoller.Filter { - ret := _m.Called() +// Close provides a mock function with given fields: qopts +func (_m *MockReader) Close(qopts ...pg.QOpt) error { + _va := make([]interface{}, len(qopts)) + for _i := range qopts { + _va[_i] = qopts[_i] + } + var _ca []interface{} + _ca = append(_ca, _va...) + ret := _m.Called(_ca...) - var r0 []logpoller.Filter - if rf, ok := ret.Get(0).(func() []logpoller.Filter); ok { - r0 = rf() + var r0 error + if rf, ok := ret.Get(0).(func(...pg.QOpt) error); ok { + r0 = rf(qopts...) } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]logpoller.Filter) - } + r0 = ret.Error(0) } return r0 diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go index 18e2479ca0..684df2bf4d 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc.go @@ -11,23 +11,21 @@ import ( "strings" "sync" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/pkg/errors" - "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/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/utils" ) const ( - apiVersion = "v1" - attestationPath = "attestations" - MESSAGE_SENT_FILTER_NAME = "USDC message sent" + apiVersion = "v1" + attestationPath = "attestations" ) type attestationStatus string @@ -37,20 +35,6 @@ const ( attestationStatusPending attestationStatus = "pending_confirmations" ) -// usdcPayload has to match the onchain event emitted by the USDC message transmitter -type usdcPayload []byte - -func (d usdcPayload) AbiString() string { - return `[{"type": "bytes"}]` -} - -func (d usdcPayload) Validate() error { - if len(d) == 0 { - return errors.New("must be non-empty") - } - return nil -} - // messageAndAttestation has to match the onchain struct `MessageAndAttestation` in the // USDC token pool. type messageAndAttestation struct { @@ -80,13 +64,9 @@ func (m messageAndAttestation) Validate() error { } type TokenDataReader struct { - lggr logger.Logger - sourceChainEvents ccipdata.Reader - attestationApi *url.URL - messageTransmitter common.Address - sourceToken common.Address - onRampAddress common.Address - + lggr logger.Logger + usdcReader ccipdata.USDCReader + attestationApi *url.URL // Cache of sequence number -> usdc message body usdcMessageHashCache map[uint64][]byte usdcMessageHashCacheMutex sync.Mutex @@ -99,14 +79,11 @@ type attestationResponse struct { var _ tokendata.Reader = &TokenDataReader{} -func NewUSDCTokenDataReader(lggr logger.Logger, sourceChainEvents ccipdata.Reader, usdcTokenAddress, usdcMessageTransmitterAddress, onRampAddress common.Address, usdcAttestationApi *url.URL) *TokenDataReader { +func NewUSDCTokenDataReader(lggr logger.Logger, usdcReader ccipdata.USDCReader, usdcAttestationApi *url.URL) *TokenDataReader { return &TokenDataReader{ - lggr: lggr.With("tokenDataProvider", "usdc"), - sourceChainEvents: sourceChainEvents, + lggr: lggr, + usdcReader: usdcReader, attestationApi: usdcAttestationApi, - messageTransmitter: usdcMessageTransmitterAddress, - onRampAddress: onRampAddress, - sourceToken: usdcTokenAddress, usdcMessageHashCache: make(map[uint64][]byte), } } @@ -160,16 +137,10 @@ func (s *TokenDataReader) getUSDCMessageBody(ctx context.Context, msg internal.E return body, nil } - usdcMessageBody, err := s.sourceChainEvents.GetLastUSDCMessagePriorToLogIndexInTx(ctx, int64(msg.LogIndex), msg.TxHash) + parsedMsgBody, err := s.usdcReader.GetLastUSDCMessagePriorToLogIndexInTx(ctx, int64(msg.LogIndex), msg.TxHash) if err != nil { return []byte{}, err } - - parsedMsgBody, err := decodeUSDCMessageSent(usdcMessageBody) - if err != nil { - return []byte{}, errors.Wrap(err, "failed parsing solidity struct") - } - s.lggr.Infow("Got USDC message body", "messageBody", hexutil.Encode(parsedMsgBody), "messageID", hexutil.Encode(msg.MessageId[:])) // Save the attempt in the cache in case the external call fails @@ -177,14 +148,6 @@ func (s *TokenDataReader) getUSDCMessageBody(ctx context.Context, msg internal.E return parsedMsgBody, nil } -func decodeUSDCMessageSent(logData []byte) ([]byte, error) { - decodeAbiStruct, err := abihelpers.DecodeAbiStruct[usdcPayload](logData) - if err != nil { - return nil, err - } - return decodeAbiStruct, nil -} - func (s *TokenDataReader) callAttestationApi(ctx context.Context, usdcMessageHash [32]byte) (attestationResponse, error) { fullAttestationUrl := fmt.Sprintf("%s/%s/%s/0x%x", s.attestationApi, apiVersion, attestationPath, usdcMessageHash) req, err := http.NewRequestWithContext(ctx, "GET", fullAttestationUrl, nil) @@ -215,12 +178,6 @@ func (s *TokenDataReader) callAttestationApi(ctx context.Context, usdcMessageHas return response, nil } -func (s *TokenDataReader) GetSourceLogPollerFilters() []logpoller.Filter { - return []logpoller.Filter{ - { - Name: logpoller.FilterName(MESSAGE_SENT_FILTER_NAME, s.messageTransmitter.Hex()), - EventSigs: []common.Hash{abihelpers.EventSignatures.USDCMessageSent}, - Addresses: []common.Address{s.messageTransmitter}, - }, - } +func (s *TokenDataReader) Close(qopts ...pg.QOpt) error { + return s.usdcReader.Close(qopts...) } diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go index 26ba789cf1..b31f2ab389 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_blackbox_test.go @@ -7,78 +7,38 @@ import ( "net/http" "net/http/httptest" "net/url" - "strings" "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_offramp" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/logger" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/tokendata/usdc" "github.com/smartcontractkit/chainlink/v2/core/utils" ) -var ( - mockOnRampAddress = utils.RandomAddress() - mockUSDCTokenAddress = utils.RandomAddress() - mockMsgTransmitter = utils.RandomAddress() -) - type attestationResponse struct { Status string `json:"status"` Attestation string `json:"attestation"` } -type messageAndAttestation struct { - Message []byte - Attestation []byte -} - -func (m messageAndAttestation) AbiString() string { - return ` - [{ - "components": [ - {"name": "message", "type": "bytes"}, - {"name": "attestation", "type": "bytes"} - ], - "type": "tuple" - }]` -} - -func (m messageAndAttestation) Validate() error { - return nil -} - -type usdcPayload []byte - -func (d usdcPayload) AbiString() string { - return `[{"type": "bytes"}]` -} - -func (d usdcPayload) Validate() error { - return nil -} - func TestUSDCReader_ReadTokenData(t *testing.T) { response := attestationResponse{ Status: "complete", Attestation: "0x9049623e91719ef2aa63c55f357be2529b0e7122ae552c18aff8db58b4633c4d3920ff03d3a6d1ddf11f06bf64d7fd60d45447ac81f527ba628877dc5ca759651b08ffae25a6d3b1411749765244f0a1c131cbfe04430d687a2e12fd9d2e6dc08e118ad95d94ad832332cf3c4f7a4f3da0baa803b7be024b02db81951c0f0714de1b", } - abiEncodedMessageBody, err := hexutil.Decode("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000") - require.NoError(t, err) - rawMessageBody, err := abihelpers.DecodeAbiStruct[usdcPayload](abiEncodedMessageBody) - require.NoError(t, err) + // Message is the bytes itself from MessageSend(bytes message) + // i.e. ABI parsed. + message := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" + expectedMessageAndAttestation := "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861000000000000000000000000000000000000000000000000000000000000000000000000000000829049623e91719ef2aa63c55f357be2529b0e7122ae552c18aff8db58b4633c4d3920ff03d3a6d1ddf11f06bf64d7fd60d45447ac81f527ba628877dc5ca759651b08ffae25a6d3b1411749765244f0a1c131cbfe04430d687a2e12fd9d2e6dc08e118ad95d94ad832332cf3c4f7a4f3da0baa803b7be024b02db81951c0f0714de1b000000000000000000000000000000000000000000000000000000000000" + lggr := logger.TestLogger(t) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - messageHash := utils.Keccak256Fixed(rawMessageBody) + messageHash := utils.Keccak256Fixed(hexutil.MustDecode(message)) expectedUrl := "/v1/attestations/0x" + hex.EncodeToString(messageHash[:]) require.Equal(t, expectedUrl, r.URL.Path) @@ -95,50 +55,24 @@ func TestUSDCReader_ReadTokenData(t *testing.T) { txHash := utils.RandomBytes32() logIndex := int64(4) - eventsClient := ccipdata.MockReader{} - eventsClient.On("GetSendRequestsBetweenSeqNums", - mock.Anything, - mockOnRampAddress, - seqNum, - seqNum, - 0, - ).Return([]ccipdata.Event[evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested]{ - { - Data: evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested{ - Raw: types.Log{ - TxHash: txHash, - Index: uint(logIndex), - }, - }, - }, - }, nil) - - eventsClient.On("GetLastUSDCMessagePriorToLogIndexInTx", + usdcReader := ccipdata.MockUSDCReader{} + usdcReader.On("GetLastUSDCMessagePriorToLogIndexInTx", mock.Anything, logIndex, common.Hash(txHash), - ).Return(abiEncodedMessageBody, nil) + ).Return(hexutil.MustDecode(message), nil) attestationURI, err := url.ParseRequestURI(ts.URL) require.NoError(t, err) - usdcService := usdc.NewUSDCTokenDataReader(logger.TestLogger(t), &eventsClient, mockUSDCTokenAddress, mockMsgTransmitter, mockOnRampAddress, attestationURI) + usdcService := usdc.NewUSDCTokenDataReader(lggr, &usdcReader, attestationURI) msgAndAttestation, err := usdcService.ReadTokenData(context.Background(), internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{ - InternalEVM2EVMMessage: evm_2_evm_offramp.InternalEVM2EVMMessage{ + EVM2EVMMessage: internal.EVM2EVMMessage{ SequenceNumber: seqNum, }, TxHash: txHash, LogIndex: uint(logIndex), }) require.NoError(t, err) - - attestationBytes, err := hex.DecodeString(strings.TrimPrefix(response.Attestation, "0x")) - require.NoError(t, err) - - encodeAbiStruct, err := abihelpers.EncodeAbiStruct[messageAndAttestation](messageAndAttestation{ - Message: rawMessageBody, - Attestation: attestationBytes, - }) - require.NoError(t, err) - - require.Equal(t, encodeAbiStruct, msgAndAttestation) + // Expected attestation for parsed body. + require.Equal(t, expectedMessageAndAttestation, hexutil.Encode(msgAndAttestation)) } diff --git a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go index b383b5e228..4f7b8fa05f 100644 --- a/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go +++ b/core/services/ocr2/plugins/ccip/tokendata/usdc/usdc_test.go @@ -9,11 +9,10 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "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" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" @@ -21,9 +20,7 @@ import ( ) var ( - mockOnRampAddress = utils.RandomAddress() - mockUSDCTokenAddress = utils.RandomAddress() - mockMsgTransmitter = utils.RandomAddress() + mockMsgTransmitter = utils.RandomAddress() ) func TestUSDCReader_callAttestationApi(t *testing.T) { @@ -31,7 +28,10 @@ func TestUSDCReader_callAttestationApi(t *testing.T) { usdcMessageHash := "912f22a13e9ccb979b621500f6952b2afd6e75be7eadaed93fc2625fe11c52a2" attestationURI, err := url.ParseRequestURI("https://iris-api-sandbox.circle.com") require.NoError(t, err) - usdcService := NewUSDCTokenDataReader(logger.TestLogger(t), nil, mockUSDCTokenAddress, mockMsgTransmitter, mockOnRampAddress, attestationURI) + lggr := logger.TestLogger(t) + usdcReader, err := ccipdata.NewUSDCReader(lggr, mockMsgTransmitter, nil) + require.NoError(t, err) + usdcService := NewUSDCTokenDataReader(lggr, usdcReader, attestationURI) attestation, err := usdcService.callAttestationApi(context.Background(), [32]byte(common.FromHex(usdcMessageHash))) require.NoError(t, err) @@ -51,7 +51,12 @@ func TestUSDCReader_callAttestationApiMock(t *testing.T) { attestationURI, err := url.ParseRequestURI(ts.URL) require.NoError(t, err) - usdcService := NewUSDCTokenDataReader(logger.TestLogger(t), nil, mockUSDCTokenAddress, mockMsgTransmitter, mockOnRampAddress, attestationURI) + lggr := logger.TestLogger(t) + lp := mocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + usdcReader, err := ccipdata.NewUSDCReader(lggr, mockMsgTransmitter, lp) + require.NoError(t, err) + usdcService := NewUSDCTokenDataReader(lggr, usdcReader, attestationURI) attestation, err := usdcService.callAttestationApi(context.Background(), utils.RandomBytes32()) require.NoError(t, err) @@ -67,7 +72,12 @@ func TestUSDCReader_callAttestationApiMockError(t *testing.T) { attestationURI, err := url.ParseRequestURI(ts.URL) require.NoError(t, err) - usdcService := NewUSDCTokenDataReader(logger.TestLogger(t), nil, mockUSDCTokenAddress, mockMsgTransmitter, mockOnRampAddress, attestationURI) + lggr := logger.TestLogger(t) + lp := mocks.NewLogPoller(t) + lp.On("RegisterFilter", mock.Anything).Return(nil) + usdcReader, err := ccipdata.NewUSDCReader(lggr, mockMsgTransmitter, lp) + require.NoError(t, err) + usdcService := NewUSDCTokenDataReader(lggr, usdcReader, attestationURI) _, err = usdcService.callAttestationApi(context.Background(), utils.RandomBytes32()) require.Error(t, err) } @@ -82,47 +92,24 @@ func getMockUSDCEndpoint(t *testing.T, response attestationResponse) *httptest.S })) } -// Asserts the hard coded event signature matches Keccak256("MessageSent(bytes)") -func TestGetUSDCReaderSourceLPFilters(t *testing.T) { - usdcService := NewUSDCTokenDataReader(logger.TestLogger(t), nil, mockUSDCTokenAddress, mockMsgTransmitter, mockOnRampAddress, nil) - - filters := usdcService.GetSourceLogPollerFilters() - - require.Equal(t, 1, len(filters)) - filter := filters[0] - require.Equal(t, logpoller.FilterName(MESSAGE_SENT_FILTER_NAME, mockMsgTransmitter.Hex()), filter.Name) - hash, err := utils.Keccak256([]byte("MessageSent(bytes)")) - require.NoError(t, err) - require.Equal(t, hash, filter.EventSigs[0].Bytes()) - require.Equal(t, mockMsgTransmitter, filter.Addresses[0]) -} - func TestGetUSDCMessageBody(t *testing.T) { - expectedBody, err := hexutil.Decode("0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000f80000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc08610000000000000000") - require.NoError(t, err) - - parsedBody, err := decodeUSDCMessageSent(expectedBody) - require.NoError(t, err) - - expectedPostParse := "0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861" - - require.Equal(t, expectedPostParse, hexutil.Encode(parsedBody)) - - sourceChainEventsMock := ccipdata.MockReader{} - sourceChainEventsMock.On("GetLastUSDCMessagePriorToLogIndexInTx", mock.Anything, mock.Anything, mock.Anything).Return(expectedBody, nil) + expectedBody := []byte("0x0000000000000001000000020000000000048d71000000000000000000000000eb08f243e5d3fcff26a9e38ae5520a669f4019d000000000000000000000000023a04d5935ed8bc8e3eb78db3541f0abfb001c6e0000000000000000000000006cb3ed9b441eb674b58495c8b3324b59faff5243000000000000000000000000000000005425890298aed601595a70ab815c96711a31bc65000000000000000000000000ab4f961939bfe6a93567cc57c59eed7084ce2131000000000000000000000000000000000000000000000000000000000000271000000000000000000000000035e08285cfed1ef159236728f843286c55fc0861") + usdcReader := ccipdata.MockUSDCReader{} + usdcReader.On("GetLastUSDCMessagePriorToLogIndexInTx", mock.Anything, mock.Anything, mock.Anything).Return(expectedBody, nil) - usdcService := NewUSDCTokenDataReader(logger.TestLogger(t), &sourceChainEventsMock, mockUSDCTokenAddress, mockMsgTransmitter, mockOnRampAddress, nil) + lggr := logger.TestLogger(t) + usdcService := NewUSDCTokenDataReader(lggr, &usdcReader, nil) // Make the first call and assert the underlying function is called body, err := usdcService.getUSDCMessageBody(context.Background(), internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{}) require.NoError(t, err) - require.Equal(t, body, parsedBody) + require.Equal(t, body, expectedBody) - sourceChainEventsMock.AssertNumberOfCalls(t, "GetLastUSDCMessagePriorToLogIndexInTx", 1) + usdcReader.AssertNumberOfCalls(t, "GetLastUSDCMessagePriorToLogIndexInTx", 1) // Make another call and assert that the cache is used body, err = usdcService.getUSDCMessageBody(context.Background(), internal.EVM2EVMOnRampCCIPSendRequestedWithMeta{}) require.NoError(t, err) - require.Equal(t, body, parsedBody) - sourceChainEventsMock.AssertNumberOfCalls(t, "GetLastUSDCMessagePriorToLogIndexInTx", 1) + require.Equal(t, body, expectedBody) + usdcReader.AssertNumberOfCalls(t, "GetLastUSDCMessagePriorToLogIndexInTx", 1) } diff --git a/core/services/ocr2/plugins/ccip/vars.go b/core/services/ocr2/plugins/ccip/vars.go index 78e5fe55f6..840465892c 100644 --- a/core/services/ocr2/plugins/ccip/vars.go +++ b/core/services/ocr2/plugins/ccip/vars.go @@ -11,4 +11,4 @@ const ( ExecPluginLabel = "exec" ) -var ErrCommitStoreIsDown = errors.New("commitStore is down") +var ErrCommitStoreIsDown = errors.New("commitStoreReader is down") diff --git a/core/services/ocr2/plugins/functions/reporting.go b/core/services/ocr2/plugins/functions/reporting.go index 9f6c6848ed..f2e2f86aba 100644 --- a/core/services/ocr2/plugins/functions/reporting.go +++ b/core/services/ocr2/plugins/functions/reporting.go @@ -62,6 +62,11 @@ var ( Help: "Metric to track number of reporting plugin Report calls", }, []string{"jobID"}) + promReportingPluginsReportNumObservations = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Name: "functions_reporting_plugin_report_num_observations", + Help: "Metric to track number of observations available in the report phase", + }, []string{"jobID"}) + promReportingAcceptReports = promauto.NewCounterVec(prometheus.CounterOpts{ Name: "functions_reporting_plugin_accept", Help: "Metric to track number of accepting reports", @@ -265,6 +270,7 @@ func (r *functionsReporting) Report(ctx context.Context, ts types.ReportTimestam "oracleID": r.genericConfig.OracleID, "nObservations": len(obs), }) + promReportingPluginsReportNumObservations.WithLabelValues(r.jobID.String()).Set(float64(len(obs))) queryProto := &encoding.Query{} err := proto.Unmarshal(query, queryProto) diff --git a/core/services/ocr2/plugins/median/services.go b/core/services/ocr2/plugins/median/services.go index e435ee747f..8d121083f3 100644 --- a/core/services/ocr2/plugins/median/services.go +++ b/core/services/ocr2/plugins/median/services.go @@ -49,7 +49,7 @@ func NewMedianServices(ctx context.Context, isNewlyCreatedJob bool, relayer loop.Relayer, pipelineRunner pipeline.Runner, - runResults chan pipeline.Run, + runResults chan *pipeline.Run, lggr logger.Logger, argsNoPlugin libocr.OCR2OracleArgs, cfg MedianConfig, @@ -70,7 +70,7 @@ func NewMedianServices(ctx context.Context, provider, err := relayer.NewPluginProvider(ctx, types.RelayArgs{ ExternalJobID: jb.ExternalJobID, - JobID: spec.ID, + JobID: jb.ID, ContractID: spec.ContractID, New: isNewlyCreatedJob, RelayConfig: spec.RelayConfig.Bytes(), diff --git a/core/services/ocr2/plugins/mercury/plugin.go b/core/services/ocr2/plugins/mercury/plugin.go index 05e7e968f8..31fb8ab8c4 100644 --- a/core/services/ocr2/plugins/mercury/plugin.go +++ b/core/services/ocr2/plugins/mercury/plugin.go @@ -32,7 +32,7 @@ func NewServices( jb job.Job, ocr2Provider relaytypes.MercuryProvider, pipelineRunner pipeline.Runner, - runResults chan pipeline.Run, + runResults chan *pipeline.Run, lggr logger.Logger, argsNoPlugin libocr2.MercuryOracleArgs, cfg Config, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go b/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go index 82cad9d4a5..3f574158e3 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm20/registry.go @@ -52,7 +52,7 @@ var ( ErrContextCancelled = fmt.Errorf("context was cancelled") ErrABINotParsable = fmt.Errorf("error parsing abi") ActiveUpkeepIDBatchSize int64 = 1000 - FetchUpkeepConfigBatchSize = 10 + FetchUpkeepConfigBatchSize = 50 separator = "|" reInitializationDelay = 15 * time.Minute logEventLookback int64 = 250 @@ -332,6 +332,9 @@ func (r *EvmRegistry) initialize() error { } offset += batch + + // Do not bombard RPC will calls, wait a bit + time.Sleep(100 * time.Millisecond) } r.mu.Lock() diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go index db50b32214..d353099470 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline.go @@ -31,6 +31,9 @@ func (r *EvmRegistry) CheckUpkeeps(ctx context.Context, keys ...ocr2keepers.Upke for i := range keys { if keys[i].Trigger.BlockNumber == 0 { // check block was not populated, use latest latest := r.bs.latestBlock.Load() + if latest == nil { + return nil, fmt.Errorf("no latest block available") + } 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) @@ -124,6 +127,13 @@ func (r *EvmRegistry) verifyCheckBlock(_ context.Context, checkBlock, upkeepId * 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[:]) + checkBlockHash := common.BytesToHash(p.Trigger.BlockHash[:]) + if checkBlockHash.String() == logBlockHash.String() { + // log verification would be covered by checkBlock verification as they are the same. Return early from + // log verificaion. This also helps in preventing some racy conditions when rpc does not return the tx receipt + // for a very new log + return encoding.UpkeepFailureReasonNone, encoding.NoPipelineError, false + } // if log block number is populated, check log block number and block hash if logBlockNumber != 0 { h, ok := r.bs.queryBlocksMap(logBlockNumber) @@ -242,13 +252,17 @@ func (r *EvmRegistry) checkUpkeeps(ctx context.Context, payloads []ocr2keepers.U for i, req := range checkReqs { index := indices[i] if req.Error != nil { + latestBlockNumber := int64(0) latestBlock := r.bs.latestBlock.Load() + if latestBlock != nil { + latestBlockNumber = int64(latestBlock.Number) + } checkBlock, _, _ := r.getBlockAndUpkeepId(payloads[index].UpkeepID, payloads[index].Trigger) // Exploratory: remove reliance on primitive way of checking errors blockNotFound := (strings.Contains(req.Error.Error(), "header not found") || strings.Contains(req.Error.Error(), "missing trie node")) - if blockNotFound && int64(latestBlock.Number)-checkBlock.Int64() > checkBlockTooOldRange { + if blockNotFound && latestBlockNumber-checkBlock.Int64() > checkBlockTooOldRange { // Check block not found in RPC and it is too old, non-retryable error - r.lggr.Warnf("block not found error encountered in check result for upkeepId %s, check block %d, latest block %d: %s", results[index].UpkeepID.String(), checkBlock.Int64(), int64(latestBlock.Number), req.Error) + r.lggr.Warnf("block not found error encountered in check result for upkeepId %s, check block %d, latest block %d: %s", results[index].UpkeepID.String(), checkBlock.Int64(), latestBlockNumber, req.Error) results[index].Retryable = false results[index].PipelineExecutionState = uint8(encoding.CheckBlockTooOld) } else { 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 index cdb5e50b5b..ee21364319 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/registry_check_pipeline_test.go @@ -75,7 +75,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { tests := []struct { name string checkBlock *big.Int - latestBlock ocr2keepers.BlockKey + latestBlock *ocr2keepers.BlockKey upkeepId *big.Int checkHash common.Hash payload ocr2keepers.UpkeepPayload @@ -88,7 +88,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { { 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}, + latestBlock: &ocr2keepers.BlockKey{Number: 560}, upkeepId: big.NewInt(12345), checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), payload: ocr2keepers.UpkeepPayload{ @@ -112,7 +112,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { { 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}, + latestBlock: &ocr2keepers.BlockKey{Number: 560}, upkeepId: big.NewInt(12345), checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), payload: ocr2keepers.UpkeepPayload{ @@ -136,7 +136,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { { name: "check block hash does not match", checkBlock: big.NewInt(500), - latestBlock: ocr2keepers.BlockKey{Number: 560}, + latestBlock: &ocr2keepers.BlockKey{Number: 560}, upkeepId: big.NewInt(12345), checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), payload: ocr2keepers.UpkeepPayload{ @@ -161,7 +161,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { { name: "check block is valid", checkBlock: big.NewInt(500), - latestBlock: ocr2keepers.BlockKey{Number: 560}, + latestBlock: &ocr2keepers.BlockKey{Number: 560}, upkeepId: big.NewInt(12345), checkHash: common.HexToHash("0x5bff03de234fe771ac0d685f9ee0fb0b757ea02ec9e6f10e8e2ee806db1b6b83"), payload: ocr2keepers.UpkeepPayload{ @@ -182,7 +182,7 @@ func TestRegistry_VerifyCheckBlock(t *testing.T) { latestBlock: atomic.Pointer[ocr2keepers.BlockKey]{}, blocks: tc.blocks, } - bs.latestBlock.Store(&tc.latestBlock) + bs.latestBlock.Store(tc.latestBlock) e := &EvmRegistry{ lggr: lggr, bs: bs, @@ -392,7 +392,7 @@ func TestRegistry_CheckUpkeeps(t *testing.T) { name string inputs []ocr2keepers.UpkeepPayload blocks map[int64]string - latestBlock ocr2keepers.BlockKey + latestBlock *ocr2keepers.BlockKey results []ocr2keepers.CheckResult err error ethCalls map[string]bool @@ -427,7 +427,7 @@ func TestRegistry_CheckUpkeeps(t *testing.T) { 570: "0x1222d75217e2dd461cc77e4091c37abe76277430d97f1963a822b4e94ebb83fc", 575: "0x9840e5b709bfccf6a1b44f34c884bc39403f57923f3f5ead6243cc090546b857", }, - latestBlock: ocr2keepers.BlockKey{Number: 580}, + latestBlock: &ocr2keepers.BlockKey{Number: 580}, results: []ocr2keepers.CheckResult{ { PipelineExecutionState: uint8(encoding.CheckBlockInvalid), @@ -494,7 +494,7 @@ func TestRegistry_CheckUpkeeps(t *testing.T) { latestBlock: atomic.Pointer[ocr2keepers.BlockKey]{}, blocks: tc.blocks, } - bs.latestBlock.Store(&tc.latestBlock) + bs.latestBlock.Store(tc.latestBlock) e := &EvmRegistry{ lggr: lggr, bs: bs, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go index 2155b38300..6c1789de9c 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup.go @@ -66,10 +66,10 @@ type MercuryV03Response struct { } type MercuryV03Report struct { - FeedID []byte `json:"feedID"` // feed id in hex + FeedID string `json:"feedID"` // feed id in hex encoded ValidFromTimestamp uint32 `json:"validFromTimestamp"` ObservationsTimestamp uint32 `json:"observationsTimestamp"` - FullReport []byte `json:"fullReport"` // the actual mercury report of this feed, can be sent to verifier + FullReport string `json:"fullReport"` // the actual hex encoded mercury report of this feed, can be sent to verifier } type MercuryData struct { @@ -528,6 +528,7 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryDa } else if resp.StatusCode == 420 { // in 0.3, this will happen when missing/malformed query args, missing or bad required headers, non-existent feeds, or no permissions for feeds retryable = false + state = encoding.InvalidMercuryRequest return fmt.Errorf("at timestamp %s upkeep %s received status code %d from mercury v0.3, most likely this is caused by missing/malformed query args, missing or bad required headers, non-existent feeds, or no permissions for feeds", sl.time.String(), sl.upkeepId.String(), resp.StatusCode) } else if resp.StatusCode != http.StatusOK { retryable = false @@ -549,13 +550,21 @@ func (r *EvmRegistry) multiFeedsRequest(ctx context.Context, ch chan<- MercuryDa // hence, retry in this case. retry will help when we send a very new timestamp and reports are not yet generated if len(response.Reports) != len(sl.feeds) { // TODO: AUTO-5044: calculate what reports are missing and log a warning + lggr.Warnf("at timestamp %s upkeep %s mercury v0.3 server retruned 200 status with %d reports while we requested %d feeds, treating as 404 (not found) and retrying", sl.time.String(), sl.upkeepId.String(), len(response.Reports), len(sl.feeds)) retryable = true state = encoding.MercuryFlakyFailure return fmt.Errorf("%d", http.StatusNotFound) } var reportBytes [][]byte for _, rsp := range response.Reports { - reportBytes = append(reportBytes, rsp.FullReport) + b, err := hexutil.Decode(rsp.FullReport) + if err != nil { + lggr.Warnf("at timestamp %s upkeep %s failed to decode reportBlob %s: %v", sl.time.String(), sl.upkeepId.String(), rsp.FullReport, err) + retryable = false + state = encoding.InvalidMercuryResponse + return err + } + reportBytes = append(reportBytes, b) } ch <- MercuryData{ Index: 0, diff --git a/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go index 42aeecb64f..f59cec18c1 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evm21/streams_lookup_test.go @@ -731,16 +731,16 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { response: &MercuryV03Response{ Reports: []MercuryV03Report{ { - FeedID: hexutil.MustDecode("0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", ValidFromTimestamp: 123456, ObservationsTimestamp: 123456, - FullReport: hexutil.MustDecode("0xab2123dc00000012"), + FullReport: "0xab2123dc00000012", }, { - FeedID: hexutil.MustDecode("0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"), + FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", ValidFromTimestamp: 123458, ObservationsTimestamp: 123458, - FullReport: hexutil.MustDecode("0xab2123dc00000016"), + FullReport: "0xab2123dc00000016", }, }, }, @@ -761,20 +761,49 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { response: &MercuryV03Response{ Reports: []MercuryV03Report{ { - FeedID: hexutil.MustDecode("0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", ValidFromTimestamp: 123456, ObservationsTimestamp: 123456, - FullReport: hexutil.MustDecode("0xab2123dc00000012"), + FullReport: "0xab2123dc00000012", }, { - FeedID: hexutil.MustDecode("0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"), + FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", ValidFromTimestamp: 123458, ObservationsTimestamp: 123458, - FullReport: hexutil.MustDecode("0xab2123dc00000019"), + FullReport: "0xab2123dc00000019", }, }, }, }, + { + name: "failure - fail to decode reportBlob", + lookup: &StreamsLookup{ + 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: "qerwiu", // invalid hex blob + }, + { + FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", + ValidFromTimestamp: 123458, + ObservationsTimestamp: 123458, + FullReport: "0xab2123dc00000016", + }, + }, + }, + statusCode: http.StatusOK, + retryable: false, + errorMessage: "All attempts fail:\n#1: hex string without 0x prefix", + }, { name: "failure - returns retryable", lookup: &StreamsLookup{ @@ -839,26 +868,26 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { firstResponse: &MercuryV03Response{ Reports: []MercuryV03Report{ { - FeedID: hexutil.MustDecode("0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", ValidFromTimestamp: 123456, ObservationsTimestamp: 123456, - FullReport: hexutil.MustDecode("0xab2123dc00000012"), + FullReport: "0xab2123dc00000012", }, }, }, response: &MercuryV03Response{ Reports: []MercuryV03Report{ { - FeedID: hexutil.MustDecode("0x4554482d5553442d415242495452554d2d544553544e45540000000000000000"), + FeedID: "0x4554482d5553442d415242495452554d2d544553544e45540000000000000000", ValidFromTimestamp: 123456, ObservationsTimestamp: 123456, - FullReport: hexutil.MustDecode("0xab2123dc00000012"), + FullReport: "0xab2123dc00000012", }, { - FeedID: hexutil.MustDecode("0x4254432d5553442d415242495452554d2d544553544e45540000000000000000"), + FeedID: "0x4254432d5553442d415242495452554d2d544553544e45540000000000000000", ValidFromTimestamp: 123458, ObservationsTimestamp: 123458, - FullReport: hexutil.MustDecode("0xab2123dc00000019"), + FullReport: "0xab2123dc00000019", }, }, }, @@ -930,7 +959,8 @@ func TestEvmRegistry_MultiFeedRequest(t *testing.T) { assert.Nil(t, m.Error) var reports [][]byte for _, rsp := range tt.response.Reports { - reports = append(reports, rsp.FullReport) + b, _ := hexutil.Decode(rsp.FullReport) + reports = append(reports, b) } assert.Equal(t, reports, m.Bytes) } diff --git a/core/services/ocr2/plugins/s4/plugin.go b/core/services/ocr2/plugins/s4/plugin.go index 23041b3b91..68bd9fd214 100644 --- a/core/services/ocr2/plugins/s4/plugin.go +++ b/core/services/ocr2/plugins/s4/plugin.go @@ -79,9 +79,9 @@ func (c *plugin) Query(ctx context.Context, ts types.ReportTimestamp) (types.Que c.addressRange.Advance() c.logger.Debug("S4StorageReporting Query", commontypes.LogFields{ - "epoch": ts.Epoch, - "round": ts.Round, - "nRows": len(rows), + "epoch": ts.Epoch, + "round": ts.Round, + "nSnapshotRows": len(rows), }) return queryBytes, err @@ -129,18 +129,20 @@ func (c *plugin) Observation(ctx context.Context, ts types.ReportTimestamp, quer snapshotVersionsMap := snapshotToVersionMap(snapshot) toBeAdded := make([]rkey, 0) + // Add rows from query snapshot that have a higher version locally. for _, qr := range queryRows { address := UnmarshalAddress(qr.Address) k := key{address: address.String(), slotID: uint(qr.Slotid)} if version, ok := snapshotVersionsMap[k]; ok && version > qr.Version { toBeAdded = append(toBeAdded, rkey{address: address, slotID: uint(qr.Slotid)}) - delete(snapshotVersionsMap, k) } + delete(snapshotVersionsMap, k) } if len(toBeAdded) > maxRemainingRows { toBeAdded = toBeAdded[:maxRemainingRows] } else { + // Add rows from query address range that exist locally but are missing from query snapshot. for _, sr := range snapshot { if !sr.Confirmed { continue @@ -180,6 +182,7 @@ func (c *plugin) Report(_ context.Context, ts types.ReportTimestamp, _ types.Que promReportingPluginReport.WithLabelValues(c.config.ProductName).Inc() reportMap := make(map[key]*Row) + reportKeys := []key{} for _, ao := range aos { observationRows, err := UnmarshalRows(ao.Observation) @@ -202,11 +205,13 @@ func (c *plugin) Report(_ context.Context, ts types.ReportTimestamp, _ types.Que continue } reportMap[mkey] = row + reportKeys = append(reportKeys, mkey) } } reportRows := make([]*Row, 0) - for _, row := range reportMap { + for _, key := range reportKeys { + row := reportMap[key] reportRows = append(reportRows, row) if len(reportRows) >= int(c.config.MaxReportEntries) { @@ -221,9 +226,10 @@ func (c *plugin) Report(_ context.Context, ts types.ReportTimestamp, _ types.Que promReportingPluginsReportRowsCount.WithLabelValues(c.config.ProductName).Set(float64(len(reportRows))) c.logger.Debug("S4StorageReporting Report", commontypes.LogFields{ - "epoch": ts.Epoch, - "round": ts.Round, - "nReportRows": len(reportRows), + "epoch": ts.Epoch, + "round": ts.Round, + "nReportRows": len(reportRows), + "nObservations": len(aos), }) return true, report, nil @@ -247,6 +253,16 @@ func (c *plugin) ShouldAcceptFinalizedReport(ctx context.Context, ts types.Repor Confirmed: true, Signature: row.Signature, } + + now := time.Now().UnixMilli() + if now > ormRow.Expiration { + c.logger.Error("Received an expired entry in a report, not saving", commontypes.LogFields{ + "expirationTs": ormRow.Expiration, + "nowTs": now, + }) + continue + } + err = c.orm.Update(ormRow, pg.WithParentCtx(ctx)) if err != nil && !errors.Is(err, s4.ErrVersionTooLow) { c.logger.Error("Failed to Update a row in ShouldAcceptFinalizedReport()", commontypes.LogFields{"err": err}) diff --git a/core/services/ocr2/plugins/s4/plugin_test.go b/core/services/ocr2/plugins/s4/plugin_test.go index 0d37103936..94c876a4f7 100644 --- a/core/services/ocr2/plugins/s4/plugin_test.go +++ b/core/services/ocr2/plugins/s4/plugin_test.go @@ -235,6 +235,21 @@ func TestPlugin_ShouldAcceptFinalizedReport(t *testing.T) { assert.NoError(t, err) // errors just logged assert.False(t, should) }) + + t.Run("don't save expired", func(t *testing.T) { + ormRows := make([]*s4_svc.Row, 0) + rows := generateTestRows(t, 2, -time.Minute) + + report, err := proto.Marshal(&s4.Rows{ + Rows: rows, + }) + assert.NoError(t, err) + + should, err := plugin.ShouldAcceptFinalizedReport(testutils.Context(t), types.ReportTimestamp{}, report) + assert.NoError(t, err) + assert.False(t, should) + assert.Equal(t, 0, len(ormRows)) + }) } func TestPlugin_Query(t *testing.T) { @@ -345,7 +360,7 @@ func TestPlugin_Observation(t *testing.T) { ormRows := generateTestOrmRows(t, int(config.MaxObservationEntries), time.Minute) snapshot := make([]*s4_svc.SnapshotRow, len(ormRows)) for i, or := range ormRows { - or.Confirmed = i < numUnconfirmed + or.Confirmed = i < numUnconfirmed // First half are confirmed or.Version = uint64(i) snapshot[i] = &s4_svc.SnapshotRow{ Address: or.Address, @@ -355,21 +370,23 @@ func TestPlugin_Observation(t *testing.T) { } } orm.On("DeleteExpired", uint(10), mock.Anything, mock.Anything).Return(int64(10), nil).Once() - orm.On("GetUnconfirmedRows", config.MaxObservationEntries, mock.Anything).Return(ormRows[:numUnconfirmed], nil).Once() + orm.On("GetUnconfirmedRows", config.MaxObservationEntries, mock.Anything).Return(ormRows[numUnconfirmed:], nil).Once() orm.On("GetSnapshot", mock.Anything, mock.Anything).Return(snapshot, nil).Once() snapshotRows := rowsToShapshotRows(ormRows) query := &s4.Query{ Rows: make([]*s4.SnapshotRow, len(snapshotRows)), } + numHigherVersion := 2 for i, v := range snapshotRows { query.Rows[i] = &s4.SnapshotRow{ Address: v.Address.Bytes(), Slotid: uint32(v.SlotId), Version: v.Version, } - if i < 5 { + if i < numHigherVersion { ormRows[i].Version++ + snapshot[i].Version++ orm.On("Get", v.Address, v.SlotId, mock.Anything).Return(ormRows[i], nil).Once() } } @@ -382,11 +399,66 @@ func TestPlugin_Observation(t *testing.T) { rows := &s4.Rows{} err = proto.Unmarshal(observation, rows) assert.NoError(t, err) - assert.Len(t, rows.Rows, int(config.MaxObservationEntries)) + assert.Len(t, rows.Rows, numUnconfirmed+numHigherVersion) for i := 0; i < numUnconfirmed; i++ { - assert.Equal(t, ormRows[i].Version, rows.Rows[i].Version) + assert.Equal(t, ormRows[numUnconfirmed+i].Version, rows.Rows[i].Version) + } + for i := 0; i < numHigherVersion; i++ { + assert.Equal(t, ormRows[i].Version, rows.Rows[numUnconfirmed+i].Version) + } + }) + + t.Run("missing from query", func(t *testing.T) { + vLow, vHigh := uint64(2), uint64(5) + ormRows := generateTestOrmRows(t, 3, time.Minute) + // Follower node has 3 confirmed entries with latest versions. + snapshot := make([]*s4_svc.SnapshotRow, len(ormRows)) + for i, or := range ormRows { + or.Confirmed = true + or.Version = vHigh + snapshot[i] = &s4_svc.SnapshotRow{ + Address: or.Address, + SlotId: or.SlotId, + Version: or.Version, + Confirmed: or.Confirmed, + } + } + + // Query snapshot has: + // - First entry with same version + // - Second entry with lower version + // - Third entry missing + query := &s4.Query{ + Rows: []*s4.SnapshotRow{ + &s4.SnapshotRow{ + Address: snapshot[0].Address.Bytes(), + Slotid: uint32(snapshot[0].SlotId), + Version: vHigh, + }, + &s4.SnapshotRow{ + Address: snapshot[1].Address.Bytes(), + Slotid: uint32(snapshot[1].SlotId), + Version: vLow, + }, + }, } + queryBytes, err := proto.Marshal(query) + assert.NoError(t, err) + + orm.On("DeleteExpired", uint(10), mock.Anything, mock.Anything).Return(int64(10), nil).Once() + orm.On("GetUnconfirmedRows", config.MaxObservationEntries, mock.Anything).Return([]*s4_svc.Row{}, nil).Once() + orm.On("GetSnapshot", mock.Anything, mock.Anything).Return(snapshot, nil).Once() + orm.On("Get", snapshot[1].Address, snapshot[1].SlotId, mock.Anything).Return(ormRows[1], nil).Once() + orm.On("Get", snapshot[2].Address, snapshot[2].SlotId, mock.Anything).Return(ormRows[2], nil).Once() + + observation, err := plugin.Observation(testutils.Context(t), types.ReportTimestamp{}, queryBytes) + assert.NoError(t, err) + + rows := &s4.Rows{} + err = proto.Unmarshal(observation, rows) + assert.NoError(t, err) + assert.Len(t, rows.Rows, 2) }) } @@ -419,4 +491,15 @@ func TestPlugin_Report(t *testing.T) { err = proto.Unmarshal(report, reportRows) assert.NoError(t, err) assert.Len(t, reportRows.Rows, 10) + + ok2, report2, err2 := plugin.Report(testutils.Context(t), types.ReportTimestamp{}, nil, aos) + assert.NoError(t, err2) + assert.True(t, ok2) + + reportRows2 := &s4.Rows{} + err = proto.Unmarshal(report2, reportRows2) + assert.NoError(t, err) + + // Verify that the same report was produced + assert.Equal(t, reportRows, reportRows2) } diff --git a/core/services/ocr2/plugins/threshold/decryption_queue.go b/core/services/ocr2/plugins/threshold/decryption_queue.go index 1ffc63e589..442fcffe8b 100644 --- a/core/services/ocr2/plugins/threshold/decryption_queue.go +++ b/core/services/ocr2/plugins/threshold/decryption_queue.go @@ -148,7 +148,7 @@ func (dq *decryptionQueue) GetRequests(requestCountLimit int, totalBytesLimit in pendingRequest, exists := dq.pendingRequests[string(ciphertextId)] if !exists { - dq.lggr.Debugf("pending decryption request for ciphertextId %s expired", ciphertextId) + dq.lggr.Debugf("decryption request for ciphertextId %s already processed or expired", ciphertextId) indicesToRemove[i] = struct{}{} continue } @@ -232,7 +232,7 @@ func (dq *decryptionQueue) SetResult(ciphertextId decryptionPlugin.CiphertextId, // 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", ciphertextId) + dq.lggr.Debugf("removing completed decryption result for ciphertextId %s from cache", ciphertextId) dq.mu.Lock() delete(dq.completedRequests, string(ciphertextId)) dq.mu.Unlock() diff --git a/core/services/ocr2/testhelpers/onchain_config.go b/core/services/ocr2/testhelpers/onchain_config.go new file mode 100644 index 0000000000..ec7e619b93 --- /dev/null +++ b/core/services/ocr2/testhelpers/onchain_config.go @@ -0,0 +1,31 @@ +package testhelpers + +import ( + "math/big" + + "github.com/smartcontractkit/libocr/bigbigendian" +) + +func GenerateDefaultOCR2OnchainConfig(minValue *big.Int, maxValue *big.Int) ([]byte, error) { + serializedConfig := make([]byte, 0) + + s1, err := bigbigendian.SerializeSigned(1, big.NewInt(1)) //version + if err != nil { + return nil, err + } + serializedConfig = append(serializedConfig, s1...) + + s2, err := bigbigendian.SerializeSigned(24, minValue) //min + if err != nil { + return nil, err + } + serializedConfig = append(serializedConfig, s2...) + + s3, err := bigbigendian.SerializeSigned(24, maxValue) //max + if err != nil { + return nil, err + } + serializedConfig = append(serializedConfig, s3...) + + return serializedConfig, nil +} diff --git a/core/services/ocrbootstrap/delegate.go b/core/services/ocrbootstrap/delegate.go index d530797367..9f9efca68e 100644 --- a/core/services/ocrbootstrap/delegate.go +++ b/core/services/ocrbootstrap/delegate.go @@ -76,10 +76,10 @@ func (d *Delegate) BeforeJobCreated(spec job.Job) { } // ServicesForSpec satisfies the job.Delegate interface. -func (d *Delegate) ServicesForSpec(jobSpec job.Job, qopts ...pg.QOpt) (services []job.ServiceCtx, err error) { - spec := jobSpec.BootstrapSpec +func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) (services []job.ServiceCtx, err error) { + spec := jb.BootstrapSpec if spec == nil { - return nil, errors.Errorf("Bootstrap.Delegate expects an *job.BootstrapSpec to be present, got %v", jobSpec) + return nil, errors.Errorf("Bootstrap.Delegate expects an *job.BootstrapSpec to be present, got %v", jb) } if d.peerWrapper == nil { return nil, errors.New("cannot setup OCR2 job service, libp2p peer was missing") @@ -101,8 +101,8 @@ func (d *Delegate) ServicesForSpec(jobSpec job.Job, qopts ...pg.QOpt) (services } ctxVals := loop.ContextValues{ - JobID: jobSpec.ID, - JobName: jobSpec.Name.ValueOrZero(), + JobID: jb.ID, + JobName: jb.Name.ValueOrZero(), ContractID: spec.ContractID, FeedID: spec.FeedID, } @@ -121,8 +121,8 @@ func (d *Delegate) ServicesForSpec(jobSpec job.Job, qopts ...pg.QOpt) (services configProvider, err = relayer.NewPluginProvider( ctx, types.RelayArgs{ - ExternalJobID: jobSpec.ExternalJobID, - JobID: spec.ID, + ExternalJobID: jb.ExternalJobID, + JobID: jb.ID, ContractID: spec.ContractID, RelayConfig: spec.RelayConfig.Bytes(), New: d.isNewlyCreatedJob, @@ -134,8 +134,8 @@ func (d *Delegate) ServicesForSpec(jobSpec job.Job, qopts ...pg.QOpt) (services ) } else { configProvider, err = relayer.NewConfigProvider(ctx, types.RelayArgs{ - ExternalJobID: jobSpec.ExternalJobID, - JobID: spec.ID, + ExternalJobID: jb.ExternalJobID, + JobID: jb.ID, ContractID: spec.ContractID, New: d.isNewlyCreatedJob, RelayConfig: spec.RelayConfig.Bytes(), @@ -166,7 +166,7 @@ func (d *Delegate) ServicesForSpec(jobSpec job.Job, qopts ...pg.QOpt) (services Database: NewDB(d.db.DB, spec.ID, lggr), LocalConfig: lc, Logger: relaylogger.NewOCRWrapper(lggr.Named("OCRBootstrap"), d.ocr2Cfg.TraceLogging(), func(msg string) { - logger.Sugared(lggr).ErrorIf(d.jobORM.RecordError(jobSpec.ID, msg), "unable to record error") + logger.Sugared(lggr).ErrorIf(d.jobORM.RecordError(jb.ID, msg), "unable to record error") }), OffchainConfigDigester: configProvider.OffchainConfigDigester(), } diff --git a/core/services/ocrcommon/data_source.go b/core/services/ocrcommon/data_source.go index 4ea7cb7a9a..ed832e45fc 100644 --- a/core/services/ocrcommon/data_source.go +++ b/core/services/ocrcommon/data_source.go @@ -35,7 +35,7 @@ type inMemoryDataSource struct { type dataSourceBase struct { inMemoryDataSource - runResults chan<- pipeline.Run + runResults chan<- *pipeline.Run } // dataSource implements dataSourceBase with the proper Observe return type for ocr1 @@ -55,7 +55,7 @@ type ObservationTimestamp struct { ConfigDigest string } -func NewDataSourceV1(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, lggr logger.Logger, runResults chan<- pipeline.Run, chEnhancedTelemetry chan EnhancedTelemetryData) ocr1types.DataSource { +func NewDataSourceV1(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, lggr logger.Logger, runResults chan<- *pipeline.Run, chEnhancedTelemetry chan EnhancedTelemetryData) ocr1types.DataSource { return &dataSource{ dataSourceBase: dataSourceBase{ inMemoryDataSource: inMemoryDataSource{ @@ -70,7 +70,7 @@ func NewDataSourceV1(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, lggr lo } } -func NewDataSourceV2(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, lggr logger.Logger, runResults chan<- pipeline.Run, enhancedTelemChan chan EnhancedTelemetryData) median.DataSource { +func NewDataSourceV2(pr pipeline.Runner, jb job.Job, spec pipeline.Spec, lggr logger.Logger, runResults chan<- *pipeline.Run, enhancedTelemChan chan EnhancedTelemetryData) median.DataSource { return &dataSourceV2{ dataSourceBase: dataSourceBase{ inMemoryDataSource: inMemoryDataSource{ @@ -113,7 +113,7 @@ func (ds *inMemoryDataSource) currentAnswer() (*big.Int, *big.Int) { // 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 *inMemoryDataSource) executeRun(ctx context.Context, timestamp ObservationTimestamp) (pipeline.Run, pipeline.FinalResult, error) { +func (ds *inMemoryDataSource) executeRun(ctx context.Context, timestamp ObservationTimestamp) (*pipeline.Run, pipeline.FinalResult, error) { md, err := bridges.MarshalBridgeMetaData(ds.currentAnswer()) if err != nil { ds.lggr.Warnw("unable to attach metadata for run", "err", err) @@ -132,7 +132,7 @@ func (ds *inMemoryDataSource) executeRun(ctx context.Context, timestamp Observat run, trrs, err := ds.pipelineRunner.ExecuteRun(ctx, ds.spec, vars, ds.lggr) if err != nil { - return pipeline.Run{}, pipeline.FinalResult{}, errors.Wrapf(err, "error executing run for spec ID %v", ds.spec.ID) + return nil, pipeline.FinalResult{}, errors.Wrapf(err, "error executing run for spec ID %v", ds.spec.ID) } finalResult := trrs.FinalResult(ds.lggr) promSetBridgeParseMetrics(ds, &trrs) diff --git a/core/services/ocrcommon/data_source_test.go b/core/services/ocrcommon/data_source_test.go index f40637cd99..51a004f1f0 100644 --- a/core/services/ocrcommon/data_source_test.go +++ b/core/services/ocrcommon/data_source_test.go @@ -28,7 +28,7 @@ var ( func Test_InMemoryDataSource(t *testing.T) { runner := pipelinemocks.NewRunner(t) runner.On("ExecuteRun", mock.Anything, mock.AnythingOfType("pipeline.Spec"), mock.Anything, mock.Anything). - Return(pipeline.Run{}, pipeline.TaskRunResults{ + Return(&pipeline.Run{}, pipeline.TaskRunResults{ { Result: pipeline.Result{ Value: mockValue, @@ -65,7 +65,7 @@ func Test_InMemoryDataSourceWithProm(t *testing.T) { }}, []pipeline.Task{}, 2) runner.On("ExecuteRun", mock.Anything, mock.AnythingOfType("pipeline.Spec"), mock.Anything, mock.Anything). - Return(pipeline.Run{}, pipeline.TaskRunResults([]pipeline.TaskRunResult{ + Return(&pipeline.Run{}, pipeline.TaskRunResults([]pipeline.TaskRunResult{ { Task: &bridgeTask, Result: pipeline.Result{}, @@ -96,7 +96,7 @@ func Test_InMemoryDataSourceWithProm(t *testing.T) { func Test_NewDataSourceV2(t *testing.T) { runner := pipelinemocks.NewRunner(t) runner.On("ExecuteRun", mock.Anything, mock.AnythingOfType("pipeline.Spec"), mock.Anything, mock.Anything). - Return(pipeline.Run{}, pipeline.TaskRunResults{ + Return(&pipeline.Run{}, pipeline.TaskRunResults{ { Result: pipeline.Result{ Value: mockValue, @@ -106,18 +106,18 @@ func Test_NewDataSourceV2(t *testing.T) { }, }, nil) - resChan := make(chan pipeline.Run, 100) + resChan := make(chan *pipeline.Run, 100) ds := ocrcommon.NewDataSourceV2(runner, job.Job{}, pipeline.Spec{}, logger.TestLogger(t), resChan, nil) val, err := ds.Observe(testutils.Context(t), types.ReportTimestamp{}) require.NoError(t, err) - assert.Equal(t, mockValue, val.String()) // returns expected value after pipeline run - assert.Equal(t, pipeline.Run{}, <-resChan) // expected data properly passed to channel + assert.Equal(t, mockValue, val.String()) // returns expected value after pipeline run + assert.Equal(t, &pipeline.Run{}, <-resChan) // expected data properly passed to channel } func Test_NewDataSourceV1(t *testing.T) { runner := pipelinemocks.NewRunner(t) runner.On("ExecuteRun", mock.Anything, mock.AnythingOfType("pipeline.Spec"), mock.Anything, mock.Anything). - Return(pipeline.Run{}, pipeline.TaskRunResults{ + Return(&pipeline.Run{}, pipeline.TaskRunResults{ { Result: pipeline.Result{ Value: mockValue, @@ -127,10 +127,10 @@ func Test_NewDataSourceV1(t *testing.T) { }, }, nil) - resChan := make(chan pipeline.Run, 100) + resChan := make(chan *pipeline.Run, 100) ds := ocrcommon.NewDataSourceV1(runner, job.Job{}, pipeline.Spec{}, logger.TestLogger(t), resChan, nil) val, err := ds.Observe(testutils.Context(t), ocrtypes.ReportTimestamp{}) require.NoError(t, err) assert.Equal(t, mockValue, new(big.Int).Set(val).String()) // returns expected value after pipeline run - assert.Equal(t, pipeline.Run{}, <-resChan) // expected data properly passed to channel + assert.Equal(t, &pipeline.Run{}, <-resChan) // expected data properly passed to channel } diff --git a/core/services/ocrcommon/run_saver.go b/core/services/ocrcommon/run_saver.go index 7a7ea0c9d0..3aa3aff876 100644 --- a/core/services/ocrcommon/run_saver.go +++ b/core/services/ocrcommon/run_saver.go @@ -12,7 +12,7 @@ type RunResultSaver struct { utils.StartStopOnce maxSuccessfulRuns uint64 - runResults <-chan pipeline.Run + runResults <-chan *pipeline.Run pipelineRunner pipeline.Runner done chan struct{} logger logger.Logger @@ -24,7 +24,7 @@ func (r *RunResultSaver) HealthReport() map[string]error { func (r *RunResultSaver) Name() string { return r.logger.Name() } -func NewResultRunSaver(runResults <-chan pipeline.Run, pipelineRunner pipeline.Runner, done chan struct{}, +func NewResultRunSaver(runResults <-chan *pipeline.Run, pipelineRunner pipeline.Runner, done chan struct{}, logger logger.Logger, maxSuccessfulRuns uint64, ) *RunResultSaver { return &RunResultSaver{ @@ -51,7 +51,7 @@ func (r *RunResultSaver) Start(context.Context) error { r.logger.Tracew("RunSaver: saving job run", "run", run) // We do not want save successful TaskRuns as OCR runs very frequently so a lot of records // are produced and the successful TaskRuns do not provide value. - if err := r.pipelineRunner.InsertFinishedRun(&run, false); err != nil { + if err := r.pipelineRunner.InsertFinishedRun(run, false); err != nil { r.logger.Errorw("error inserting finished results", "err", err) } case <-r.done: @@ -73,7 +73,7 @@ func (r *RunResultSaver) Close() error { select { case run := <-r.runResults: r.logger.Infow("RunSaver: saving job run before exiting", "run", run) - if err := r.pipelineRunner.InsertFinishedRun(&run, false); err != nil { + if err := r.pipelineRunner.InsertFinishedRun(run, false); err != nil { r.logger.Errorw("error inserting finished results", "err", err) } default: diff --git a/core/services/ocrcommon/run_saver_test.go b/core/services/ocrcommon/run_saver_test.go index 0f24f93e97..7d20a7a202 100644 --- a/core/services/ocrcommon/run_saver_test.go +++ b/core/services/ocrcommon/run_saver_test.go @@ -14,7 +14,7 @@ import ( func TestRunSaver(t *testing.T) { pipelineRunner := mocks.NewRunner(t) - rr := make(chan pipeline.Run, 100) + rr := make(chan *pipeline.Run, 100) rs := NewResultRunSaver( rr, pipelineRunner, @@ -31,7 +31,7 @@ func TestRunSaver(t *testing.T) { args.Get(0).(*pipeline.Run).ID = int64(d) }). Once() - rr <- pipeline.Run{ID: int64(i)} + rr <- &pipeline.Run{ID: int64(i)} } require.NoError(t, rs.Close()) } diff --git a/core/services/ocrcommon/telemetry.go b/core/services/ocrcommon/telemetry.go index 636a18262e..54a5002093 100644 --- a/core/services/ocrcommon/telemetry.go +++ b/core/services/ocrcommon/telemetry.go @@ -3,6 +3,7 @@ package ocrcommon import ( "context" "encoding/json" + "fmt" "github.com/ethereum/go-ethereum/common" @@ -353,7 +354,7 @@ func ShouldCollectEnhancedTelemetryMercury(job *job.Job) bool { // bid and ask. This functions expects the pipeline.TaskRunResults to be correctly ordered func (e *EnhancedTelemetryService[T]) getPricesFromResults(startTask pipeline.TaskRunResult, allTasks *pipeline.TaskRunResults) (float64, float64, float64) { var benchmarkPrice, askPrice, bidPrice float64 - var ok bool + var err error //We rely on task results to be sorted in the correct order benchmarkPriceTask := allTasks.GetNextTaskOf(startTask) if benchmarkPriceTask == nil { @@ -361,33 +362,45 @@ func (e *EnhancedTelemetryService[T]) getPricesFromResults(startTask pipeline.Ta return 0, 0, 0 } if benchmarkPriceTask.Task.Type() == pipeline.TaskTypeJSONParse { - benchmarkPrice, ok = benchmarkPriceTask.Result.Value.(float64) - if !ok { - e.lggr.Warnf("cannot parse enhanced EA telemetry benchmark price, job %d, id %s", e.job.ID, benchmarkPriceTask.Task.DotID()) + if benchmarkPriceTask.Result.Error != nil { + e.lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry benchmark price, job %d, id %s: %s", e.job.ID, benchmarkPriceTask.Task.DotID(), benchmarkPriceTask.Result.Error), "err", benchmarkPriceTask.Result.Error) + } else { + benchmarkPrice, err = getResultFloat64(benchmarkPriceTask) + if err != nil { + e.lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry benchmark price, job %d, id %s", e.job.ID, benchmarkPriceTask.Task.DotID()), "err", err) + } } } bidTask := allTasks.GetNextTaskOf(*benchmarkPriceTask) if bidTask == nil { e.lggr.Warnf("cannot parse enhanced EA telemetry bid price, task is nil, job %d, id %s", e.job.ID) - return 0, 0, 0 + return benchmarkPrice, 0, 0 } if bidTask.Task.Type() == pipeline.TaskTypeJSONParse { - bidPrice, ok = bidTask.Result.Value.(float64) - if !ok { - e.lggr.Warnf("cannot parse enhanced EA telemetry bid price, job %d, id %s", e.job.ID, bidTask.Task.DotID()) + if bidTask.Result.Error != nil { + e.lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry bid price, job %d, id %s: %s", e.job.ID, bidTask.Task.DotID(), bidTask.Result.Error), "err", bidTask.Result.Error) + } else { + bidPrice, err = getResultFloat64(bidTask) + if err != nil { + e.lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry bid price, job %d, id %s", e.job.ID, bidTask.Task.DotID()), "err", err) + } } } askTask := allTasks.GetNextTaskOf(*bidTask) if askTask == nil { e.lggr.Warnf("cannot parse enhanced EA telemetry ask price, task is nil, job %d, id %s", e.job.ID) - return 0, 0, 0 + return benchmarkPrice, bidPrice, 0 } if askTask.Task.Type() == pipeline.TaskTypeJSONParse { - askPrice, ok = askTask.Result.Value.(float64) - if !ok { - e.lggr.Warnf("cannot parse enhanced EA telemetry ask price, job %d, id %s", e.job.ID, askTask.Task.DotID()) + if bidTask.Result.Error != nil { + e.lggr.Warnw(fmt.Sprintf("got error for enhanced EA telemetry ask price, job %d, id %s: %s", e.job.ID, askTask.Task.DotID(), askTask.Result.Error), "err", askTask.Result.Error) + } else { + askPrice, err = getResultFloat64(askTask) + if err != nil { + e.lggr.Warnw(fmt.Sprintf("cannot parse enhanced EA telemetry ask price, job %d, id %s", e.job.ID, askTask.Task.DotID()), "err", err) + } } } @@ -418,3 +431,13 @@ func EnqueueEnhancedTelem[T EnhancedTelemetryData | EnhancedTelemetryMercuryData default: } } + +// getResultFloat64 will check the result type and force it to float64 or returns an error if the conversion cannot be made +func getResultFloat64(task *pipeline.TaskRunResult) (float64, error) { + result, err := utils.ToDecimal(task.Result.Value) + if err != nil { + return 0, err + } + resultFloat64, _ := result.Float64() + return resultFloat64, nil +} diff --git a/core/services/ocrcommon/telemetry_test.go b/core/services/ocrcommon/telemetry_test.go index e7c41c4676..495dc6fe78 100644 --- a/core/services/ocrcommon/telemetry_test.go +++ b/core/services/ocrcommon/telemetry_test.go @@ -416,7 +416,7 @@ var trrsMercury = pipeline.TaskRunResults{ BaseTask: pipeline.NewBaseTask(3, "ds3_ask", nil, nil, 3), }, Result: pipeline.Result{ - Value: float64(123456789.1), + Value: int64(321123), }, }, } @@ -461,7 +461,7 @@ func TestGetPricesFromResults(t *testing.T) { benchmarkPrice, bid, ask := e.getPricesFromResults(trrsMercury[0], &trrsMercury) require.Equal(t, 123456.123456, benchmarkPrice) require.Equal(t, 1234567.1234567, bid) - require.Equal(t, 123456789.1, ask) + require.Equal(t, float64(321123), ask) benchmarkPrice, bid, ask = e.getPricesFromResults(trrsMercury[0], &pipeline.TaskRunResults{}) require.Equal(t, float64(0), benchmarkPrice) @@ -601,7 +601,7 @@ func TestCollectMercuryEnhancedTelemetry(t *testing.T) { DataSource: "data-source-name", DpBenchmarkPrice: 123456.123456, DpBid: 1234567.1234567, - DpAsk: 123456789.1, + DpAsk: 321123, CurrentBlockNumber: 123456789, CurrentBlockHash: common.HexToHash("0x123321").String(), CurrentBlockTimestamp: 987654321, diff --git a/core/services/ocrcommon/transmitter_pipeline.go b/core/services/ocrcommon/transmitter_pipeline.go index d07be5a540..e62f745a94 100644 --- a/core/services/ocrcommon/transmitter_pipeline.go +++ b/core/services/ocrcommon/transmitter_pipeline.go @@ -81,7 +81,7 @@ func (t *pipelineTransmitter) CreateEthTransaction(ctx context.Context, toAddres t.spec.PipelineSpec.DotDagSource = txObservationSource run := pipeline.NewRun(*t.spec.PipelineSpec, vars) - if _, err := t.pr.Run(ctx, &run, t.lgr, true, nil); err != nil { + if _, err := t.pr.Run(ctx, run, t.lgr, true, nil); err != nil { return errors.Wrap(err, "Skipped OCR transmission") } diff --git a/core/services/pipeline/mocks/runner.go b/core/services/pipeline/mocks/runner.go index a43498c100..e2cc70378e 100644 --- a/core/services/pipeline/mocks/runner.go +++ b/core/services/pipeline/mocks/runner.go @@ -66,19 +66,21 @@ func (_m *Runner) ExecuteAndInsertFinishedRun(ctx context.Context, spec pipeline } // ExecuteRun provides a mock function with given fields: ctx, spec, vars, l -func (_m *Runner) ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (pipeline.Run, pipeline.TaskRunResults, error) { +func (_m *Runner) ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (*pipeline.Run, pipeline.TaskRunResults, error) { ret := _m.Called(ctx, spec, vars, l) - var r0 pipeline.Run + var r0 *pipeline.Run var r1 pipeline.TaskRunResults var r2 error - if rf, ok := ret.Get(0).(func(context.Context, pipeline.Spec, pipeline.Vars, logger.Logger) (pipeline.Run, pipeline.TaskRunResults, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, pipeline.Spec, pipeline.Vars, logger.Logger) (*pipeline.Run, pipeline.TaskRunResults, error)); ok { return rf(ctx, spec, vars, l) } - if rf, ok := ret.Get(0).(func(context.Context, pipeline.Spec, pipeline.Vars, logger.Logger) pipeline.Run); ok { + if rf, ok := ret.Get(0).(func(context.Context, pipeline.Spec, pipeline.Vars, logger.Logger) *pipeline.Run); ok { r0 = rf(ctx, spec, vars, l) } else { - r0 = ret.Get(0).(pipeline.Run) + if ret.Get(0) != nil { + r0 = ret.Get(0).(*pipeline.Run) + } } if rf, ok := ret.Get(1).(func(context.Context, pipeline.Spec, pipeline.Vars, logger.Logger) pipeline.TaskRunResults); ok { diff --git a/core/services/pipeline/runner.go b/core/services/pipeline/runner.go index 7a755e8fe1..3366a177ba 100644 --- a/core/services/pipeline/runner.go +++ b/core/services/pipeline/runner.go @@ -38,7 +38,7 @@ type Runner interface { // ExecuteRun executes a new run in-memory according to a spec and returns the results. // We expect spec.JobID and spec.JobName to be set for logging/prometheus. - ExecuteRun(ctx context.Context, spec Spec, vars Vars, l logger.Logger) (run Run, trrs TaskRunResults, err error) + ExecuteRun(ctx context.Context, spec Spec, vars Vars, l logger.Logger) (run *Run, trrs TaskRunResults, err error) // InsertFinishedRun saves the run results in the database. InsertFinishedRun(run *Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error InsertFinishedRuns(runs []*Run, saveSuccessfulTaskRuns bool, qopts ...pg.QOpt) error @@ -196,8 +196,8 @@ func (err ErrRunPanicked) Error() string { return fmt.Sprintf("goroutine panicked when executing run: %v", err.v) } -func NewRun(spec Spec, vars Vars) Run { - return Run{ +func NewRun(spec Spec, vars Vars) *Run { + return &Run{ State: RunStatusRunning, PipelineSpec: spec, PipelineSpecID: spec.ID, @@ -218,16 +218,16 @@ func (r *runner) ExecuteRun( spec Spec, vars Vars, l logger.Logger, -) (Run, TaskRunResults, error) { +) (*Run, TaskRunResults, error) { run := NewRun(spec, vars) - pipeline, err := r.initializePipeline(&run) + pipeline, err := r.initializePipeline(run) if err != nil { return run, nil, err } - taskRunResults := r.run(ctx, pipeline, &run, vars, l) + taskRunResults := r.run(ctx, pipeline, run, vars, l) if run.Pending { return run, nil, pkgerrors.Wrapf(err, "unexpected async run for spec ID %v, tried executing via ExecuteAndInsertFinishedRun", spec.ID) @@ -505,7 +505,7 @@ func (r *runner) ExecuteAndInsertFinishedRun(ctx context.Context, spec Spec, var return 0, finalResult, nil } - if err = r.orm.InsertFinishedRun(&run, saveSuccessfulTaskRuns); err != nil { + if err = r.orm.InsertFinishedRun(run, saveSuccessfulTaskRuns); err != nil { return 0, finalResult, pkgerrors.Wrapf(err, "error inserting finished results for spec ID %v", spec.ID) } return run.ID, finalResult, nil diff --git a/core/services/pipeline/runner_test.go b/core/services/pipeline/runner_test.go index 2554315a46..22b70829ba 100644 --- a/core/services/pipeline/runner_test.go +++ b/core/services/pipeline/runner_test.go @@ -635,7 +635,7 @@ ds5 [type=http method="GET" url="%s" index=2] }).Once() orm.On("StoreRun", mock.AnythingOfType("*pipeline.Run"), mock.Anything).Return(false, nil).Once() lggr := logger.TestLogger(t) - incomplete, err := r.Run(testutils.Context(t), &run, lggr, false, nil) + incomplete, err := r.Run(testutils.Context(t), run, lggr, false, nil) require.NoError(t, err) require.Len(t, run.PipelineTaskRuns, 9) // 3 tasks are suspended: ds1_parse, ds1_multiply, median. ds1 is present, but contains ErrPending require.Equal(t, true, incomplete) // still incomplete @@ -644,7 +644,7 @@ ds5 [type=http method="GET" url="%s" index=2] // Trigger run resumption with no new data orm.On("StoreRun", mock.AnythingOfType("*pipeline.Run")).Return(false, nil).Once() - incomplete, err = r.Run(testutils.Context(t), &run, lggr, false, nil) + incomplete, err = r.Run(testutils.Context(t), run, lggr, false, nil) require.NoError(t, err) require.Equal(t, true, incomplete) // still incomplete @@ -657,7 +657,7 @@ ds5 [type=http method="GET" url="%s" index=2] } // Trigger run resumption orm.On("StoreRun", mock.AnythingOfType("*pipeline.Run"), mock.Anything).Return(false, nil).Once() - incomplete, err = r.Run(testutils.Context(t), &run, lggr, false, nil) + incomplete, err = r.Run(testutils.Context(t), run, lggr, false, nil) require.NoError(t, err) require.Equal(t, false, incomplete) // done require.Len(t, run.PipelineTaskRuns, 12) @@ -773,7 +773,7 @@ ds5 [type=http method="GET" url="%s" index=2] }).Once() // StoreRun is called again to store the final result orm.On("StoreRun", mock.AnythingOfType("*pipeline.Run"), mock.Anything).Return(false, nil).Once() - incomplete, err := r.Run(testutils.Context(t), &run, logger.TestLogger(t), false, nil) + incomplete, err := r.Run(testutils.Context(t), run, logger.TestLogger(t), false, nil) require.NoError(t, err) require.Len(t, run.PipelineTaskRuns, 12) require.Equal(t, false, incomplete) // run is complete diff --git a/core/services/pipeline/scheduler_test.go b/core/services/pipeline/scheduler_test.go index bbb9ee80b9..1d7da59da9 100644 --- a/core/services/pipeline/scheduler_test.go +++ b/core/services/pipeline/scheduler_test.go @@ -135,7 +135,7 @@ func TestScheduler(t *testing.T) { require.NoError(t, err) vars := NewVarsFrom(nil) run := NewRun(Spec{}, vars) - s := newScheduler(p, &run, vars, logger.TestLogger(t)) + s := newScheduler(p, run, vars, logger.TestLogger(t)) go s.Run() diff --git a/core/services/pipeline/task.vrfv2plus.go b/core/services/pipeline/task.vrfv2plus.go index c998a48d74..a596bfa309 100644 --- a/core/services/pipeline/task.vrfv2plus.go +++ b/core/services/pipeline/task.vrfv2plus.go @@ -13,14 +13,14 @@ import ( "go.uber.org/multierr" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/proof" ) var ( - vrfCoordinatorV2PlusABI = evmtypes.MustGetABI(vrf_coordinator_v2plus.VRFCoordinatorV2PlusABI) + vrfCoordinatorV2PlusABI = evmtypes.MustGetABI(vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalABI) ) // VRFTaskV2Plus is identical to VRFTaskV2 except that it uses the V2Plus VRF diff --git a/core/services/relay/evm/ccip.go b/core/services/relay/evm/ccip.go index 80d8071ce7..f0ccdfe85f 100644 --- a/core/services/relay/evm/ccip.go +++ b/core/services/relay/evm/ccip.go @@ -1,12 +1,14 @@ package evm import ( + "github.com/ethereum/go-ethereum/common" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip" + ccipconfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/pg" "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" @@ -34,7 +36,16 @@ func NewCCIPCommitProvider(lggr logger.Logger, chainSet evm.Chain, rargs relayty if err != nil { return nil, err } - contractTransmitter, err := newContractTransmitter(lggr, rargs, transmitterID, configWatcher, ks, ccip.CommitReportToEthTxMeta) + address := common.HexToAddress(relayOpts.ContractID) + typ, ver, err := ccipconfig.TypeAndVersion(address, chainSet.Client()) + if err != nil { + return nil, err + } + fn, err := ccip.CommitReportToEthTxMeta(typ, ver) + if err != nil { + return nil, err + } + contractTransmitter, err := newContractTransmitter(lggr, rargs, transmitterID, configWatcher, ks, fn) if err != nil { return nil, err } @@ -62,7 +73,16 @@ func NewCCIPExecutionProvider(lggr logger.Logger, chainSet evm.Chain, rargs rela if err != nil { return nil, err } - contractTransmitter, err := newContractTransmitter(lggr, rargs, transmitterID, configWatcher, ks, ccip.ExecutionReportToEthTxMeta) + address := common.HexToAddress(relayOpts.ContractID) + typ, ver, err := ccipconfig.TypeAndVersion(address, chainSet.Client()) + if err != nil { + return nil, err + } + fn, err := ccip.ExecReportToEthTxMeta(typ, ver) + if err != nil { + return nil, err + } + contractTransmitter, err := newContractTransmitter(lggr, rargs, transmitterID, configWatcher, ks, fn) if err != nil { return nil, err } diff --git a/core/services/relay/evm/config_poller.go b/core/services/relay/evm/config_poller.go index 6d8d4588d0..504155bf1e 100644 --- a/core/services/relay/evm/config_poller.go +++ b/core/services/relay/evm/config_poller.go @@ -3,23 +3,41 @@ package evm import ( "context" "database/sql" + "fmt" "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/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" + "github.com/smartcontractkit/libocr/gethwrappers2/ocrconfigurationstoreevmsimple" ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/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/pg" evmRelayTypes "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm/types" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) -// ConfigSet Common to all OCR2 evm based contracts: https://github.com/smartcontractkit/libocr/blob/master/contract2/dev/OCR2Abstract.sol -var ConfigSet common.Hash +var ( + failedRPCContractCalls = promauto.NewCounterVec(prometheus.CounterOpts{ + Name: "ocr2_failed_rpc_contract_calls", + Help: "Running count of failed RPC contract calls by chain/contract", + }, + []string{"chainID", "contractAddress"}, + ) +) + +var ( + // ConfigSet Common to all OCR2 evm based contracts: https://github.com/smartcontractkit/libocr/blob/master/contract2/dev/OCR2Abstract.sol + ConfigSet common.Hash -var defaultABI abi.ABI + defaultABI abi.ABI +) const configSetEventName = "ConfigSet" @@ -50,7 +68,7 @@ func configFromLog(logData []byte) (ocrtypes.ContractConfig, error) { var transmitAccounts []ocrtypes.Account for _, addr := range unpacked.Transmitters { - transmitAccounts = append(transmitAccounts, ocrtypes.Account(addr.String())) + transmitAccounts = append(transmitAccounts, ocrtypes.Account(addr.Hex())) } var signers []ocrtypes.OnchainPublicKey for _, addr := range unpacked.Signers { @@ -71,36 +89,63 @@ func configFromLog(logData []byte) (ocrtypes.ContractConfig, error) { } type configPoller struct { + utils.StartStopOnce + lggr logger.Logger filterName string destChainLogPoller logpoller.LogPoller - addr common.Address + client client.Client + + aggregatorContractAddr common.Address + aggregatorContract *ocr2aggregator.OCR2Aggregator + + // Some chains "manage" state bloat by deleting older logs. The ConfigStore + // contract allows us work around such restrictions. + configStoreContractAddr *common.Address + configStoreContract *ocrconfigurationstoreevmsimple.OCRConfigurationStoreEVMSimple } func configPollerFilterName(addr common.Address) string { return logpoller.FilterName("OCR2ConfigPoller", addr.String()) } -func NewConfigPoller(lggr logger.Logger, destChainPoller logpoller.LogPoller, addr common.Address) (evmRelayTypes.ConfigPoller, error) { - err := destChainPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(addr), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{addr}}) +func NewConfigPoller(lggr logger.Logger, client client.Client, destChainPoller logpoller.LogPoller, aggregatorContractAddr common.Address, configStoreAddr *common.Address) (evmRelayTypes.ConfigPoller, error) { + return newConfigPoller(lggr, client, destChainPoller, aggregatorContractAddr, configStoreAddr) +} + +func newConfigPoller(lggr logger.Logger, client client.Client, destChainPoller logpoller.LogPoller, aggregatorContractAddr common.Address, configStoreAddr *common.Address) (*configPoller, error) { + err := destChainPoller.RegisterFilter(logpoller.Filter{Name: configPollerFilterName(aggregatorContractAddr), EventSigs: []common.Hash{ConfigSet}, Addresses: []common.Address{aggregatorContractAddr}}) + if err != nil { + return nil, err + } + + aggregatorContract, err := ocr2aggregator.NewOCR2Aggregator(aggregatorContractAddr, client) if err != nil { return nil, err } cp := &configPoller{ - lggr: lggr, - filterName: configPollerFilterName(addr), - destChainLogPoller: destChainPoller, - addr: addr, + lggr: lggr, + filterName: configPollerFilterName(aggregatorContractAddr), + destChainLogPoller: destChainPoller, + aggregatorContractAddr: aggregatorContractAddr, + client: client, + aggregatorContract: aggregatorContract, + } + + if configStoreAddr != nil { + cp.configStoreContractAddr = configStoreAddr + cp.configStoreContract, err = ocrconfigurationstoreevmsimple.NewOCRConfigurationStoreEVMSimple(*configStoreAddr, client) + if err != nil { + return nil, err + } } return cp, nil } -// Start noop method func (cp *configPoller) Start() {} -// Close noop method func (cp *configPoller) Close() error { return nil } @@ -117,10 +162,14 @@ func (cp *configPoller) Replay(ctx context.Context, fromBlock int64) error { // LatestConfigDetails returns the latest config details from the logs 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)) + latest, err := cp.destChainLogPoller.LatestLogByEventSigWithConfs(ConfigSet, cp.aggregatorContractAddr, 1, pg.WithParentCtx(ctx)) if err != nil { - // If contract is not configured, we will not have the log. if errors.Is(err, sql.ErrNoRows) { + if cp.isConfigStoreAvailable() { + // Fallback to RPC call in case logs have been pruned and configStoreContract is available + return cp.callLatestConfigDetails(ctx) + } + // log not found means return zero config digest return 0, ocrtypes.ConfigDigest{}, nil } return 0, ocrtypes.ConfigDigest{}, err @@ -134,12 +183,16 @@ func (cp *configPoller) LatestConfigDetails(ctx context.Context) (changedInBlock // LatestConfig returns the latest config from the logs on a certain block 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)) + lgs, err := cp.destChainLogPoller.Logs(int64(changedInBlock), int64(changedInBlock), ConfigSet, cp.aggregatorContractAddr, pg.WithParentCtx(ctx)) if err != nil { return ocrtypes.ContractConfig{}, err } if len(lgs) == 0 { - return ocrtypes.ContractConfig{}, errors.New("no logs found") + if cp.isConfigStoreAvailable() { + // Fallback to RPC call in case logs have been pruned + return cp.callReadConfigFromStore(ctx) + } + return ocrtypes.ContractConfig{}, fmt.Errorf("no logs found for config on contract %s (chain %s) at block %d", cp.aggregatorContractAddr.Hex(), cp.client.ConfiguredChainID().String(), changedInBlock) } latestConfigSet, err := configFromLog(lgs[len(lgs)-1].Data) if err != nil { @@ -160,3 +213,58 @@ func (cp *configPoller) LatestBlockHeight(ctx context.Context) (blockHeight uint } return uint64(latest), nil } + +func (cp *configPoller) isConfigStoreAvailable() bool { + return cp.configStoreContract != nil +} + +// RPC call for latest config details +func (cp *configPoller) callLatestConfigDetails(ctx context.Context) (changedInBlock uint64, configDigest ocrtypes.ConfigDigest, err error) { + details, err := cp.aggregatorContract.LatestConfigDetails(&bind.CallOpts{ + Context: ctx, + }) + if err != nil { + failedRPCContractCalls.WithLabelValues(cp.client.ConfiguredChainID().String(), cp.aggregatorContractAddr.Hex()).Inc() + } + return uint64(details.BlockNumber), details.ConfigDigest, err +} + +// RPC call to read config from config store contract +func (cp *configPoller) callReadConfigFromStore(ctx context.Context) (cfg ocrtypes.ContractConfig, err error) { + _, configDigest, err := cp.LatestConfigDetails(ctx) + if err != nil { + failedRPCContractCalls.WithLabelValues(cp.client.ConfiguredChainID().String(), cp.aggregatorContractAddr.Hex()).Inc() + return cfg, fmt.Errorf("failed to get latest config details: %w", err) + } + if configDigest == (ocrtypes.ConfigDigest{}) { + return cfg, fmt.Errorf("config details missing while trying to lookup config in store; no logs found for contract %s (chain %s)", cp.aggregatorContractAddr.Hex(), cp.client.ConfiguredChainID().String()) + } + + storedConfig, err := cp.configStoreContract.ReadConfig(&bind.CallOpts{ + Context: ctx, + }, configDigest) + if err != nil { + failedRPCContractCalls.WithLabelValues(cp.client.ConfiguredChainID().String(), cp.configStoreContractAddr.Hex()).Inc() + return cfg, fmt.Errorf("failed to read config from config store contract: %w", err) + } + + signers := make([]ocrtypes.OnchainPublicKey, len(storedConfig.Signers)) + for i := range signers { + signers[i] = storedConfig.Signers[i].Bytes() + } + transmitters := make([]ocrtypes.Account, len(storedConfig.Transmitters)) + for i := range transmitters { + transmitters[i] = ocrtypes.Account(storedConfig.Transmitters[i].Hex()) + } + + return ocrtypes.ContractConfig{ + ConfigDigest: configDigest, + ConfigCount: uint64(storedConfig.ConfigCount), + Signers: signers, + Transmitters: transmitters, + F: storedConfig.F, + OnchainConfig: storedConfig.OnchainConfig, + OffchainConfigVersion: storedConfig.OffchainConfigVersion, + OffchainConfig: storedConfig.OffchainConfig, + }, err +} diff --git a/core/services/relay/evm/config_poller_test.go b/core/services/relay/evm/config_poller_test.go index 75e033dfeb..73c16a1959 100644 --- a/core/services/relay/evm/config_poller_test.go +++ b/core/services/relay/evm/config_poller_test.go @@ -1,111 +1,325 @@ package evm import ( + "database/sql" "math/big" "testing" "time" + "github.com/ethereum/go-ethereum" + "github.com/smartcontractkit/libocr/gethwrappers2/ocrconfigurationstoreevmsimple" + "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/onsi/gomega" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" testoffchainaggregator2 "github.com/smartcontractkit/libocr/gethwrappers2/testocr2aggregator" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" confighelper2 "github.com/smartcontractkit/libocr/offchainreporting2plus/confighelper" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" + 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/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "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/ocr2/testhelpers" "github.com/smartcontractkit/chainlink/v2/core/utils" ) func TestConfigPoller(t *testing.T) { - 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) - linkTokenAddress, _, _, err := link_token_interface.DeployLinkToken(user, b) - require.NoError(t, err) - accessAddress, _, _, err := testoffchainaggregator2.DeploySimpleWriteAccessController(user, b) - require.NoError(t, err, "failed to deploy test access controller contract") - ocrAddress, _, ocrContract, err := ocr2aggregator.DeployOCR2Aggregator( - user, - b, - linkTokenAddress, - big.NewInt(0), - big.NewInt(10), - accessAddress, - accessAddress, - 9, - "TEST", - ) - 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) - require.NoError(t, lp.Start(ctx)) - t.Cleanup(func() { lp.Close() }) - configPoller, err := NewConfigPoller(lggr, lp, ocrAddress) - require.NoError(t, err) - // Should have no config to begin with. - _, config, err := configPoller.LatestConfigDetails(testutils.Context(t)) - require.NoError(t, err) - require.Equal(t, ocrtypes2.ConfigDigest{}, config) - _, err = configPoller.LatestConfig(testutils.Context(t), 0) - require.Error(t, err) - // Set the config - contractConfig := setConfig(t, median.OffchainConfig{ - AlphaReportInfinite: false, - AlphaReportPPB: 0, - AlphaAcceptInfinite: true, - AlphaAcceptPPB: 0, - DeltaC: 10, - }, ocrContract, user) - b.Commit() - latest, err := b.BlockByNumber(testutils.Context(t), nil) - require.NoError(t, err) - // Ensure we capture this config set log. - require.NoError(t, lp.Replay(testutils.Context(t), latest.Number().Int64()-1)) + var ethClient *client.SimulatedBackendClient + var lp logpoller.LogPoller + var ocrAddress common.Address + var ocrContract *ocr2aggregator.OCR2Aggregator + var configStoreContractAddr common.Address + var configStoreContract *ocrconfigurationstoreevmsimple.OCRConfigurationStoreEVMSimple + var user *bind.TransactOpts + var b *backends.SimulatedBackend + var linkTokenAddress common.Address + var accessAddress common.Address - // Send blocks until we see the config updated. - var configBlock uint64 - var digest [32]byte - gomega.NewGomegaWithT(t).Eventually(func() bool { + { + 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) + linkTokenAddress, _, _, err = link_token_interface.DeployLinkToken(user, b) + require.NoError(t, err) + accessAddress, _, _, err = testoffchainaggregator2.DeploySimpleWriteAccessController(user, b) + require.NoError(t, err, "failed to deploy test access controller contract") + ocrAddress, _, ocrContract, err = ocr2aggregator.DeployOCR2Aggregator( + user, + b, + linkTokenAddress, + big.NewInt(0), + big.NewInt(10), + accessAddress, + accessAddress, + 9, + "TEST", + ) + require.NoError(t, err) + configStoreContractAddr, _, configStoreContract, err = ocrconfigurationstoreevmsimple.DeployOCRConfigurationStoreEVMSimple(user, b) + require.NoError(t, err) b.Commit() - configBlock, digest, err = configPoller.LatestConfigDetails(testutils.Context(t)) + + db := pgtest.NewSqlxDB(t) + cfg := pgtest.NewQConfig(false) + ethClient = evmclient.NewSimulatedBackendClient(t, b, testutils.SimulatedChainID) + ctx := testutils.Context(t) + lorm := logpoller.NewORM(testutils.SimulatedChainID, db, lggr, cfg) + lp = logpoller.NewLogPoller(lorm, ethClient, lggr, 100*time.Millisecond, 1, 2, 2, 1000) + require.NoError(t, lp.Start(ctx)) + t.Cleanup(func() { lp.Close() }) + } + + t.Run("LatestConfig errors if there is no config in logs and config store is unconfigured", func(t *testing.T) { + cp, err := NewConfigPoller(lggr, ethClient, lp, ocrAddress, nil) 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 := configPoller.LatestConfig(testutils.Context(t), configBlock) - require.NoError(t, err) - // Note we don't check onchainConfig, as that is populated in the contract itself. - assert.Equal(t, digest, [32]byte(newConfig.ConfigDigest)) - assert.Equal(t, contractConfig.Signers, newConfig.Signers) - assert.Equal(t, contractConfig.Transmitters, newConfig.Transmitters) - assert.Equal(t, contractConfig.F, newConfig.F) - assert.Equal(t, contractConfig.OffchainConfigVersion, newConfig.OffchainConfigVersion) - assert.Equal(t, contractConfig.OffchainConfig, newConfig.OffchainConfig) + _, err = cp.LatestConfig(testutils.Context(t), 0) + require.Error(t, err) + assert.Contains(t, err.Error(), "no logs found for config on contract") + }) + + t.Run("happy path (with config store)", func(t *testing.T) { + cp, err := NewConfigPoller(lggr, ethClient, lp, ocrAddress, &configStoreContractAddr) + require.NoError(t, err) + // Should have no config to begin with. + _, configDigest, err := cp.LatestConfigDetails(testutils.Context(t)) + require.NoError(t, err) + require.Equal(t, ocrtypes2.ConfigDigest{}, configDigest) + // Should error because there are no logs for config at block 0 + _, err = cp.LatestConfig(testutils.Context(t), 0) + require.Error(t, err) + assert.Contains(t, err.Error(), "config details missing while trying to lookup config in store") + + // Set the config + contractConfig := setConfig(t, median.OffchainConfig{ + AlphaReportInfinite: false, + AlphaReportPPB: 0, + AlphaAcceptInfinite: true, + AlphaAcceptPPB: 0, + DeltaC: 10, + }, ocrContract, user) + b.Commit() + latest, err := b.BlockByNumber(testutils.Context(t), nil) + require.NoError(t, err) + // Ensure we capture this config set log. + require.NoError(t, lp.Replay(testutils.Context(t), latest.Number().Int64()-1)) + + // Send blocks until we see the config updated. + var configBlock uint64 + var digest [32]byte + gomega.NewGomegaWithT(t).Eventually(func() bool { + b.Commit() + configBlock, digest, err = cp.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 := cp.LatestConfig(testutils.Context(t), configBlock) + require.NoError(t, err) + // Note we don't check onchainConfig, as that is populated in the contract itself. + assert.Equal(t, digest, [32]byte(newConfig.ConfigDigest)) + assert.Equal(t, contractConfig.Signers, newConfig.Signers) + assert.Equal(t, contractConfig.Transmitters, newConfig.Transmitters) + assert.Equal(t, contractConfig.F, newConfig.F) + assert.Equal(t, contractConfig.OffchainConfigVersion, newConfig.OffchainConfigVersion) + assert.Equal(t, contractConfig.OffchainConfig, newConfig.OffchainConfig) + }) + + { + var err error + ocrAddress, _, ocrContract, err = ocr2aggregator.DeployOCR2Aggregator( + user, + b, + linkTokenAddress, + big.NewInt(0), + big.NewInt(10), + accessAddress, + accessAddress, + 9, + "TEST", + ) + require.NoError(t, err) + b.Commit() + } + + t.Run("LatestConfigDetails, when logs have been pruned and config store contract is configured", func(t *testing.T) { + // Give it a log poller that will never return logs + mp := new(mocks.LogPoller) + mp.On("RegisterFilter", mock.Anything).Return(nil) + mp.On("LatestLogByEventSigWithConfs", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, sql.ErrNoRows) + + t.Run("if callLatestConfigDetails succeeds", func(t *testing.T) { + cp, err := newConfigPoller(lggr, ethClient, mp, ocrAddress, &configStoreContractAddr) + require.NoError(t, err) + + t.Run("when config has not been set, returns zero values", func(t *testing.T) { + changedInBlock, configDigest, err := cp.LatestConfigDetails(testutils.Context(t)) + require.NoError(t, err) + + assert.Equal(t, 0, int(changedInBlock)) + assert.Equal(t, ocrtypes.ConfigDigest{}, configDigest) + }) + t.Run("when config has been set, returns config details", func(t *testing.T) { + setConfig(t, median.OffchainConfig{ + AlphaReportInfinite: false, + AlphaReportPPB: 0, + AlphaAcceptInfinite: true, + AlphaAcceptPPB: 0, + DeltaC: 10, + }, ocrContract, user) + b.Commit() + + changedInBlock, configDigest, err := cp.LatestConfigDetails(testutils.Context(t)) + require.NoError(t, err) + + latest, err := b.BlockByNumber(testutils.Context(t), nil) + require.NoError(t, err) + + onchainDetails, err := ocrContract.LatestConfigDetails(nil) + require.NoError(t, err) + + assert.Equal(t, latest.Number().Int64(), int64(changedInBlock)) + assert.Equal(t, onchainDetails.ConfigDigest, [32]byte(configDigest)) + }) + }) + t.Run("returns error if callLatestConfigDetails fails", func(t *testing.T) { + failingClient := new(evmClientMocks.Client) + failingClient.On("ConfiguredChainID").Return(big.NewInt(42)) + failingClient.On("CallContract", mock.Anything, mock.Anything, mock.Anything).Return(nil, errors.New("something exploded")) + cp, err := newConfigPoller(lggr, failingClient, mp, ocrAddress, &configStoreContractAddr) + require.NoError(t, err) + + cp.configStoreContractAddr = &configStoreContractAddr + cp.configStoreContract = configStoreContract + + _, _, err = cp.LatestConfigDetails(testutils.Context(t)) + assert.EqualError(t, err, "something exploded") + + failingClient.AssertExpectations(t) + }) + }) + + { + var err error + // deploy it again to reset to empty config + ocrAddress, _, ocrContract, err = ocr2aggregator.DeployOCR2Aggregator( + user, + b, + linkTokenAddress, + big.NewInt(0), + big.NewInt(10), + accessAddress, + accessAddress, + 9, + "TEST", + ) + require.NoError(t, err) + b.Commit() + } + + t.Run("LatestConfig, when logs have been pruned and config store contract is configured", func(t *testing.T) { + // Give it a log poller that will never return logs + mp := mocks.NewLogPoller(t) + mp.On("RegisterFilter", mock.Anything).Return(nil) + mp.On("Logs", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, nil) + mp.On("LatestLogByEventSigWithConfs", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, sql.ErrNoRows) + + t.Run("if callReadConfig succeeds", func(t *testing.T) { + cp, err := newConfigPoller(lggr, ethClient, mp, ocrAddress, &configStoreContractAddr) + require.NoError(t, err) + + t.Run("when config has not been set, returns error", func(t *testing.T) { + _, err := cp.LatestConfig(testutils.Context(t), 0) + require.Error(t, err) + + assert.Contains(t, err.Error(), "config details missing while trying to lookup config in store") + }) + t.Run("when config has been set, returns config", func(t *testing.T) { + b.Commit() + onchainDetails, err := ocrContract.LatestConfigDetails(nil) + require.NoError(t, err) + + contractConfig := setConfig(t, median.OffchainConfig{ + AlphaReportInfinite: false, + AlphaReportPPB: 0, + AlphaAcceptInfinite: true, + AlphaAcceptPPB: 0, + DeltaC: 10, + }, ocrContract, user) + + signerAddresses, err := OnchainPublicKeyToAddress(contractConfig.Signers) + require.NoError(t, err) + transmitterAddresses, err := AccountToAddress(contractConfig.Transmitters) + require.NoError(t, err) + + configuration := ocrconfigurationstoreevmsimple.OCRConfigurationStoreEVMSimpleConfigurationEVMSimple{ + Signers: signerAddresses, + Transmitters: transmitterAddresses, + OnchainConfig: contractConfig.OnchainConfig, + OffchainConfig: contractConfig.OffchainConfig, + ContractAddress: ocrAddress, + OffchainConfigVersion: contractConfig.OffchainConfigVersion, + ConfigCount: 1, + F: contractConfig.F, + } + + addConfig(t, user, configStoreContract, configuration) + + b.Commit() + onchainDetails, err = ocrContract.LatestConfigDetails(nil) + require.NoError(t, err) + + newConfig, err := cp.LatestConfig(testutils.Context(t), 0) + require.NoError(t, err) + + assert.Equal(t, onchainDetails.ConfigDigest, [32]byte(newConfig.ConfigDigest)) + assert.Equal(t, contractConfig.Signers, newConfig.Signers) + assert.Equal(t, contractConfig.Transmitters, newConfig.Transmitters) + assert.Equal(t, contractConfig.F, newConfig.F) + assert.Equal(t, contractConfig.OffchainConfigVersion, newConfig.OffchainConfigVersion) + assert.Equal(t, contractConfig.OffchainConfig, newConfig.OffchainConfig) + }) + }) + t.Run("returns error if callReadConfig fails", func(t *testing.T) { + failingClient := new(evmClientMocks.Client) + failingClient.On("ConfiguredChainID").Return(big.NewInt(42)) + failingClient.On("CallContract", mock.Anything, mock.MatchedBy(func(callArgs ethereum.CallMsg) bool { + // initial call to retrieve config store address from aggregator + return *callArgs.To == ocrAddress + }), mock.Anything).Return(nil, errors.New("something exploded")).Once() + cp, err := newConfigPoller(lggr, failingClient, mp, ocrAddress, &configStoreContractAddr) + require.NoError(t, err) + + _, err = cp.LatestConfig(testutils.Context(t), 0) + assert.EqualError(t, err, "failed to get latest config details: something exploded") + + failingClient.AssertExpectations(t) + }) + }) } func setConfig(t *testing.T, pluginConfig median.OffchainConfig, ocrContract *ocr2aggregator.OCR2Aggregator, user *bind.TransactOpts) ocrtypes2.ContractConfig { @@ -115,13 +329,16 @@ func setConfig(t *testing.T, pluginConfig median.OffchainConfig, ocrContract *oc oracles = append(oracles, confighelper2.OracleIdentityExtra{ OracleIdentity: confighelper2.OracleIdentity{ OnchainPublicKey: utils.RandomAddress().Bytes(), - TransmitAccount: ocrtypes2.Account(utils.RandomAddress().String()), + TransmitAccount: ocrtypes2.Account(utils.RandomAddress().Hex()), OffchainPublicKey: utils.RandomBytes32(), PeerID: utils.MustNewPeerID(), }, ConfigEncryptionPublicKey: utils.RandomBytes32(), }) } + // Gnerate OnchainConfig + onchainConfig, err := testhelpers.GenerateDefaultOCR2OnchainConfig(big.NewInt(0), big.NewInt(10)) + require.NoError(t, err) // Change the offramp config signers, transmitters, threshold, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper2.ContractSetConfigArgsForTests( 2*time.Second, // deltaProgress @@ -139,7 +356,7 @@ func setConfig(t *testing.T, pluginConfig median.OffchainConfig, ocrContract *oc 50*time.Millisecond, 50*time.Millisecond, 1, // faults - nil, + onchainConfig, ) require.NoError(t, err) signerAddresses, err := OnchainPublicKeyToAddress(signers) @@ -157,3 +374,9 @@ func setConfig(t *testing.T, pluginConfig median.OffchainConfig, ocrContract *oc OffchainConfig: offchainConfig, } } + +func addConfig(t *testing.T, user *bind.TransactOpts, configStoreContract *ocrconfigurationstoreevmsimple.OCRConfigurationStoreEVMSimple, config ocrconfigurationstoreevmsimple.OCRConfigurationStoreEVMSimpleConfigurationEVMSimple) { + + _, err := configStoreContract.AddConfig(user, config) + require.NoError(t, err) +} diff --git a/core/services/relay/evm/evm.go b/core/services/relay/evm/evm.go index 7ec87a4e77..d93f3bab6c 100644 --- a/core/services/relay/evm/evm.go +++ b/core/services/relay/evm/evm.go @@ -3,13 +3,14 @@ package evm import ( "context" "encoding/json" + "errors" "fmt" "strings" "sync" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" - "github.com/pkg/errors" + pkgerrors "github.com/pkg/errors" "github.com/smartcontractkit/libocr/gethwrappers2/ocr2aggregator" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median" "github.com/smartcontractkit/libocr/offchainreporting2/reportingplugin/median/evmreportcodec" @@ -61,17 +62,49 @@ type CSAETHKeystore interface { Eth() keystore.Eth } -func NewRelayer(db *sqlx.DB, chain evm.Chain, cfg pg.QConfig, lggr logger.Logger, ks CSAETHKeystore, eventBroadcaster pg.EventBroadcaster) *Relayer { +type RelayerOpts struct { + *sqlx.DB + pg.QConfig + CSAETHKeystore + pg.EventBroadcaster +} + +func (c RelayerOpts) Validate() error { + var err error + if c.DB == nil { + err = errors.Join(err, errors.New("nil DB")) + } + if c.QConfig == nil { + err = errors.Join(err, errors.New("nil QConfig")) + } + if c.CSAETHKeystore == nil { + err = errors.Join(err, errors.New("nil Keystore")) + } + if c.EventBroadcaster == nil { + err = errors.Join(err, errors.New("nil Eventbroadcaster")) + } + + if err != nil { + err = fmt.Errorf("invalid RelayerOpts: %w", err) + } + return err +} + +func NewRelayer(lggr logger.Logger, chain evm.Chain, opts RelayerOpts) (*Relayer, error) { + err := opts.Validate() + if err != nil { + return nil, fmt.Errorf("cannot create evm relayer: %w", err) + } lggr = lggr.Named("Relayer") return &Relayer{ - db: db, + db: opts.DB, chain: chain, lggr: lggr, - ks: ks, + ks: opts.CSAETHKeystore, mercuryPool: wsrpc.NewPool(lggr), - eventBroadcaster: eventBroadcaster, - pgCfg: cfg, - } + eventBroadcaster: opts.EventBroadcaster, + pgCfg: opts.QConfig, + }, nil } func (r *Relayer) Name() string { @@ -107,11 +140,11 @@ func (r *Relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytype var mercuryConfig mercuryconfig.PluginConfig if err := json.Unmarshal(pargs.PluginConfig, &mercuryConfig); err != nil { - return nil, errors.WithStack(err) + return nil, pkgerrors.WithStack(err) } if relayConfig.FeedID == nil { - return nil, errors.New("FeedID must be specified") + return nil, pkgerrors.New("FeedID must be specified") } feedID := mercuryutils.FeedID(*relayConfig.FeedID) @@ -120,15 +153,15 @@ func (r *Relayer) NewMercuryProvider(rargs relaytypes.RelayArgs, pargs relaytype } configWatcher, err := newConfigProvider(r.lggr, r.chain, relayOpts, r.eventBroadcaster) if err != nil { - return nil, errors.WithStack(err) + return nil, pkgerrors.WithStack(err) } if !relayConfig.EffectiveTransmitterID.Valid { - return nil, errors.New("EffectiveTransmitterID must be specified") + return nil, pkgerrors.New("EffectiveTransmitterID must be specified") } privKey, err := r.ks.CSA().Get(relayConfig.EffectiveTransmitterID.String) if err != nil { - return nil, errors.Wrap(err, "failed to get CSA key for mercury connection") + return nil, pkgerrors.Wrap(err, "failed to get CSA key for mercury connection") } client, err := r.mercuryPool.Checkout(context.Background(), privKey, mercuryConfig.ServerPubKey, mercuryConfig.ServerURL()) @@ -190,7 +223,7 @@ func FilterNamesFromRelayArgs(args relaytypes.RelayArgs) (filterNames []string, } var relayConfig types.RelayConfig if err = json.Unmarshal(args.RelayConfig, &relayConfig); err != nil { - return nil, errors.WithStack(err) + return nil, pkgerrors.WithStack(err) } if relayConfig.FeedID != nil { @@ -289,13 +322,13 @@ func (c *configWatcher) ContractConfigTracker() ocrtypes.ContractConfigTracker { 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") + return nil, pkgerrors.Errorf("invalid contractID, expected hex address") } - contractAddress := common.HexToAddress(opts.ContractID) + aggregatorAddress := 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") + return nil, pkgerrors.Wrap(err, "could not get contract ABI JSON") } var cp types.ConfigPoller @@ -307,14 +340,18 @@ func newConfigProvider(lggr logger.Logger, chain evm.Chain, opts *types.RelayOpt cp, err = mercury.NewConfigPoller( lggr, chain.LogPoller(), - contractAddress, + aggregatorAddress, *relayConfig.FeedID, eventBroadcaster, + // TODO: Does mercury need to support config contract? DF-19182 ) } else { - cp, err = NewConfigPoller(lggr, + cp, err = NewConfigPoller( + lggr, + chain.Client(), chain.LogPoller(), - contractAddress, + aggregatorAddress, + relayConfig.ConfigContractAddress, ) } if err != nil { @@ -324,15 +361,15 @@ func newConfigProvider(lggr logger.Logger, chain evm.Chain, opts *types.RelayOpt var offchainConfigDigester ocrtypes.OffchainConfigDigester if relayConfig.FeedID != nil { // Mercury - offchainConfigDigester = mercury.NewOffchainConfigDigester(*relayConfig.FeedID, chain.Config().EVM().ChainID(), contractAddress) + offchainConfigDigester = mercury.NewOffchainConfigDigester(*relayConfig.FeedID, chain.Config().EVM().ChainID(), aggregatorAddress) } else { // Non-mercury offchainConfigDigester = evmutil.EVMOffchainConfigDigester{ ChainID: chain.Config().EVM().ChainID().Uint64(), - ContractAddress: contractAddress, + ContractAddress: aggregatorAddress, } } - return newConfigWatcher(lggr, contractAddress, contractABI, offchainConfigDigester, cp, chain, relayConfig.FromBlock, opts.New), nil + return newConfigWatcher(lggr, aggregatorAddress, contractABI, offchainConfigDigester, cp, chain, relayConfig.FromBlock, opts.New), nil } func newContractTransmitter(lggr logger.Logger, rargs relaytypes.RelayArgs, transmitterID string, configWatcher *configWatcher, ethKeystore keystore.Eth, reportToEthMeta ReportToEthMetadata) (*contractTransmitter, error) { @@ -343,23 +380,23 @@ func newContractTransmitter(lggr logger.Logger, rargs relaytypes.RelayArgs, tran var fromAddresses []common.Address sendingKeys := relayConfig.SendingKeys if !relayConfig.EffectiveTransmitterID.Valid { - return nil, errors.New("EffectiveTransmitterID must be specified") + return nil, pkgerrors.New("EffectiveTransmitterID must be specified") } effectiveTransmitterAddress := common.HexToAddress(relayConfig.EffectiveTransmitterID.String) sendingKeysLength := len(sendingKeys) if sendingKeysLength == 0 { - return nil, errors.New("no sending keys provided") + return nil, pkgerrors.New("no sending keys provided") } // 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") + return nil, pkgerrors.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") + return nil, pkgerrors.Wrap(err, "one of the sending keys given is not enabled") } fromAddresses = append(fromAddresses, common.HexToAddress(s)) } @@ -390,7 +427,7 @@ func newContractTransmitter(lggr logger.Logger, rargs relaytypes.RelayArgs, tran ) if err != nil { - return nil, errors.Wrap(err, "failed to create transmitter") + return nil, pkgerrors.Wrap(err, "failed to create transmitter") } return NewOCRContractTransmitter( @@ -411,7 +448,7 @@ func newPipelineContractTransmitter(lggr logger.Logger, rargs relaytypes.RelayAr } if !relayConfig.EffectiveTransmitterID.Valid { - return nil, errors.New("EffectiveTransmitterID must be specified") + return nil, pkgerrors.New("EffectiveTransmitterID must be specified") } effectiveTransmitterAddress := common.HexToAddress(relayConfig.EffectiveTransmitterID.String) transmitterAddress := common.HexToAddress(transmitterID) diff --git a/core/services/relay/evm/evm_test.go b/core/services/relay/evm/evm_test.go new file mode 100644 index 0000000000..df7cd8eb81 --- /dev/null +++ b/core/services/relay/evm/evm_test.go @@ -0,0 +1,68 @@ +package evm_test + +import ( + "testing" + + "github.com/smartcontractkit/sqlx" + "github.com/stretchr/testify/assert" + + configtest "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest/v2" + "github.com/smartcontractkit/chainlink/v2/core/services/pg" + "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" +) + +func TestRelayerOpts_Validate(t *testing.T) { + cfg := configtest.NewTestGeneralConfig(t) + type fields struct { + DB *sqlx.DB + QConfig pg.QConfig + CSAETHKeystore evm.CSAETHKeystore + EventBroadcaster pg.EventBroadcaster + } + tests := []struct { + name string + fields fields + wantErrContains string + }{ + { + name: "all invalid", + fields: fields{ + DB: nil, + QConfig: nil, + CSAETHKeystore: nil, + EventBroadcaster: nil, + }, + wantErrContains: `nil DB +nil QConfig +nil Keystore +nil Eventbroadcaster`, + }, + { + name: "missing db, keystore", + fields: fields{ + DB: nil, + QConfig: cfg.Database(), + CSAETHKeystore: nil, + EventBroadcaster: pg.NewNullEventBroadcaster(), + }, + wantErrContains: `nil DB +nil Keystore`, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := evm.RelayerOpts{ + DB: tt.fields.DB, + QConfig: tt.fields.QConfig, + CSAETHKeystore: tt.fields.CSAETHKeystore, + EventBroadcaster: tt.fields.EventBroadcaster, + } + err := c.Validate() + if tt.wantErrContains != "" { + assert.Contains(t, err.Error(), tt.wantErrContains) + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/core/services/relay/evm/functions/config_poller_test.go b/core/services/relay/evm/functions/config_poller_test.go index b53b2751b1..d6573ef354 100644 --- a/core/services/relay/evm/functions/config_poller_test.go +++ b/core/services/relay/evm/functions/config_poller_test.go @@ -21,6 +21,7 @@ import ( ocrtypes2 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" functionsConfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/functions/config" + "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/testhelpers" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" @@ -170,6 +171,9 @@ func setFunctionsConfig(t *testing.T, pluginConfig *functionsConfig.ReportingPlu pluginConfigBytes, err := functionsConfig.EncodeReportingPluginConfig(pluginConfig) require.NoError(t, err) + onchainConfig, err := testhelpers.GenerateDefaultOCR2OnchainConfig(big.NewInt(0), big.NewInt(10)) + require.NoError(t, err) + signers, transmitters, threshold, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper2.ContractSetConfigArgsForTests( 2*time.Second, // deltaProgress 1*time.Second, // deltaResend @@ -186,7 +190,7 @@ func setFunctionsConfig(t *testing.T, pluginConfig *functionsConfig.ReportingPlu 50*time.Millisecond, 50*time.Millisecond, 1, // faults - nil, + onchainConfig, ) require.NoError(t, err) diff --git a/core/services/relay/evm/functions/logpoller_wrapper.go b/core/services/relay/evm/functions/logpoller_wrapper.go index eae1970da9..db2c7fd68c 100644 --- a/core/services/relay/evm/functions/logpoller_wrapper.go +++ b/core/services/relay/evm/functions/logpoller_wrapper.go @@ -30,6 +30,7 @@ type logPollerWrapper struct { subscribers map[string]evmRelayTypes.RouteUpdateSubscriber activeCoordinator common.Address proposedCoordinator common.Address + blockOffset int64 nextBlock int64 mu sync.Mutex closeWait sync.WaitGroup @@ -44,10 +45,15 @@ func NewLogPollerWrapper(routerContractAddress common.Address, pluginConfig conf if err != nil { return nil, err } + blockOffset := int64(pluginConfig.MinIncomingConfirmations) - 1 + if blockOffset < 0 { + blockOffset = 0 + } return &logPollerWrapper{ routerContract: routerContract, pluginConfig: pluginConfig, + blockOffset: blockOffset, logPoller: logPoller, client: client, subscribers: make(map[string]evmRelayTypes.RouteUpdateSubscriber), @@ -66,11 +72,11 @@ func (l *logPollerWrapper) Start(context.Context) error { 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.nextBlock = nextBlock - l.blockOffset } l.closeWait.Add(1) go l.checkForRouteUpdates() @@ -116,6 +122,7 @@ func (l *logPollerWrapper) LatestEvents() ([]evmRelayTypes.OracleRequest, []evmR l.mu.Unlock() return nil, nil, err } + latest -= l.blockOffset if latest >= nextBlock { l.nextBlock = latest + 1 } diff --git a/core/services/relay/evm/mercury/mocks/pipeline.go b/core/services/relay/evm/mercury/mocks/pipeline.go index 317404e440..f553ba9850 100644 --- a/core/services/relay/evm/mercury/mocks/pipeline.go +++ b/core/services/relay/evm/mercury/mocks/pipeline.go @@ -13,8 +13,8 @@ type MockRunner struct { 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 *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{} diff --git a/core/services/relay/evm/mercury/v1/data_source.go b/core/services/relay/evm/mercury/v1/data_source.go index ff7a2c0ab7..5c1f55ddab 100644 --- a/core/services/relay/evm/mercury/v1/data_source.go +++ b/core/services/relay/evm/mercury/v1/data_source.go @@ -26,7 +26,7 @@ import ( ) type Runner interface { - ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) + 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 @@ -40,7 +40,7 @@ type datasource struct { jb job.Job spec pipeline.Spec lggr logger.Logger - runResults chan<- pipeline.Run + runResults chan<- *pipeline.Run orm types.DataSourceORM codec reportcodec.ReportCodec feedID [32]byte @@ -55,7 +55,7 @@ type datasource struct { var _ relaymercuryv1.DataSource = &datasource{} -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 { +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} } @@ -115,7 +115,7 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam wg.Add(1) go func() { defer wg.Done() - var run pipeline.Run + var run *pipeline.Run run, trrs, err = ds.executeRun(ctx) if err != nil { err = fmt.Errorf("Observe failed while executing run: %w", err) @@ -238,7 +238,7 @@ func setAsk(o *parseOutput, res pipeline.Result) error { // 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) { +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, @@ -249,7 +249,7 @@ func (ds *datasource) executeRun(ctx context.Context) (pipeline.Run, pipeline.Ta 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 nil, 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/v1/data_source_test.go b/core/services/relay/evm/mercury/v1/data_source_test.go index a0932990f0..6e46095130 100644 --- a/core/services/relay/evm/mercury/v1/data_source_test.go +++ b/core/services/relay/evm/mercury/v1/data_source_test.go @@ -308,8 +308,8 @@ func TestMercury_Observe(t *testing.T) { trrs[i].Result.Value = "123" trrs[i].Result.Error = nil } + ch := make(chan *pipeline.Run, 1) - ch := make(chan pipeline.Run, 1) ds.runResults = ch _, err := ds.Observe(ctx, repts, false) diff --git a/core/services/relay/evm/mercury/v2/data_source.go b/core/services/relay/evm/mercury/v2/data_source.go index 632278a3c5..caeae8d278 100644 --- a/core/services/relay/evm/mercury/v2/data_source.go +++ b/core/services/relay/evm/mercury/v2/data_source.go @@ -25,7 +25,7 @@ import ( ) type Runner interface { - ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) + ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run *pipeline.Run, trrs pipeline.TaskRunResults, err error) } type LatestReportFetcher interface { @@ -39,7 +39,7 @@ type datasource struct { spec pipeline.Spec feedID mercuryutils.FeedID lggr logger.Logger - runResults chan<- pipeline.Run + runResults chan<- *pipeline.Run orm types.DataSourceORM codec reportcodec.ReportCodec @@ -54,7 +54,7 @@ type datasource struct { var _ relaymercuryv2.DataSource = &datasource{} -func NewDataSource(orm types.DataSourceORM, 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 { +func NewDataSource(orm types.DataSourceORM, 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, orm, reportcodec.ReportCodec{}, fetcher, linkFeedID, nativeFeedID, sync.RWMutex{}, enhancedTelemChan} } @@ -84,7 +84,7 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam go func() { defer wg.Done() var trrs pipeline.TaskRunResults - var run pipeline.Run + var run *pipeline.Run run, trrs, err = ds.executeRun(ctx) if err != nil { cancel() @@ -218,7 +218,7 @@ func setBenchmarkPrice(o *parseOutput, res pipeline.Result) error { // 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) { +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, @@ -229,7 +229,7 @@ func (ds *datasource) executeRun(ctx context.Context) (pipeline.Run, pipeline.Ta 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 nil, 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.go b/core/services/relay/evm/mercury/v3/data_source.go index 8d3895cd62..79f6c536ef 100644 --- a/core/services/relay/evm/mercury/v3/data_source.go +++ b/core/services/relay/evm/mercury/v3/data_source.go @@ -26,7 +26,7 @@ import ( ) type Runner interface { - ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run pipeline.Run, trrs pipeline.TaskRunResults, err error) + ExecuteRun(ctx context.Context, spec pipeline.Spec, vars pipeline.Vars, l logger.Logger) (run *pipeline.Run, trrs pipeline.TaskRunResults, err error) } type LatestReportFetcher interface { @@ -40,7 +40,7 @@ type datasource struct { spec pipeline.Spec feedID mercuryutils.FeedID lggr logger.Logger - runResults chan<- pipeline.Run + runResults chan<- *pipeline.Run orm types.DataSourceORM codec reportcodec.ReportCodec @@ -55,7 +55,7 @@ type datasource struct { var _ relaymercuryv3.DataSource = &datasource{} -func NewDataSource(orm types.DataSourceORM, 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 { +func NewDataSource(orm types.DataSourceORM, 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, orm, reportcodec.ReportCodec{}, fetcher, linkFeedID, nativeFeedID, sync.RWMutex{}, enhancedTelemChan} } @@ -85,7 +85,7 @@ func (ds *datasource) Observe(ctx context.Context, repts ocrtypes.ReportTimestam go func() { defer wg.Done() var trrs pipeline.TaskRunResults - var run pipeline.Run + var run *pipeline.Run run, trrs, err = ds.executeRun(ctx) if err != nil { cancel() @@ -256,7 +256,7 @@ func setAsk(o *parseOutput, res pipeline.Result) error { // 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) { +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, @@ -267,7 +267,7 @@ func (ds *datasource) executeRun(ctx context.Context) (pipeline.Run, pipeline.Ta 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 nil, 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/ocr2keeper.go b/core/services/relay/evm/ocr2keeper.go index c6f4f1ad39..baf98b9b00 100644 --- a/core/services/relay/evm/ocr2keeper.go +++ b/core/services/relay/evm/ocr2keeper.go @@ -147,8 +147,11 @@ func newOCR2KeeperConfigProvider(lggr logger.Logger, chain evm.Chain, rargs rela configPoller, err := NewConfigPoller( lggr.With("contractID", rargs.ContractID), + chain.Client(), chain.LogPoller(), contractAddress, + // TODO: Does ocr2keeper need to support config contract? DF-19182 + nil, ) if err != nil { return nil, errors.Wrap(err, "failed to create config poller") diff --git a/core/services/relay/evm/ocr2vrf.go b/core/services/relay/evm/ocr2vrf.go index 724ad4c329..a5e3f3da3f 100644 --- a/core/services/relay/evm/ocr2vrf.go +++ b/core/services/relay/evm/ocr2vrf.go @@ -135,8 +135,12 @@ func newOCR2VRFConfigProvider(lggr logger.Logger, chain evm.Chain, rargs relayty } configPoller, err := NewConfigPoller( lggr.With("contractID", rargs.ContractID), + chain.Client(), chain.LogPoller(), - contractAddress) + contractAddress, + // TODO: Does ocr2vrf need to support config contract? DF-19182 + nil, + ) if err != nil { return nil, err } diff --git a/core/services/relay/evm/relayer_extender.go b/core/services/relay/evm/relayer_extender.go index 592c9bacee..ce638d10cf 100644 --- a/core/services/relay/evm/relayer_extender.go +++ b/core/services/relay/evm/relayer_extender.go @@ -118,7 +118,7 @@ func (s *ChainRelayerExt) Ready() (err error) { } func NewChainRelayerExtenders(ctx context.Context, opts evmchain.ChainRelayExtenderConfig) (*ChainRelayerExtenders, error) { - if err := opts.Check(); err != nil { + if err := opts.Validate(); err != nil { return nil, err } @@ -143,16 +143,15 @@ func NewChainRelayerExtenders(ctx context.Context, opts evmchain.ChainRelayExten cid := enabled[i].ChainID.String() privOpts := evmchain.ChainRelayExtenderConfig{ - Logger: opts.Logger.Named(cid), - RelayerConfig: opts.RelayerConfig, - DB: opts.DB, - KeyStore: opts.KeyStore, + Logger: opts.Logger.Named(cid), + ChainOpts: opts.ChainOpts, + KeyStore: opts.KeyStore, } privOpts.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) + err = multierr.Combine(err, fmt.Errorf("failed to create chain %s: %w", cid, err2)) continue } @@ -161,5 +160,6 @@ func NewChainRelayerExtenders(ctx context.Context, opts evmchain.ChainRelayExten } result = append(result, s) } - return newChainRelayerExtsFromSlice(result, opts.AppConfig), nil + // always return because it's accumulating errors + return newChainRelayerExtsFromSlice(result, opts.AppConfig), err } diff --git a/core/services/relay/evm/types/types.go b/core/services/relay/evm/types/types.go index 8671082db2..97eddd7d9c 100644 --- a/core/services/relay/evm/types/types.go +++ b/core/services/relay/evm/types/types.go @@ -20,9 +20,10 @@ import ( ) type RelayConfig struct { - ChainID *utils.Big `json:"chainID"` - FromBlock uint64 `json:"fromBlock"` - EffectiveTransmitterID null.String `json:"effectiveTransmitterID"` + ChainID *utils.Big `json:"chainID"` + FromBlock uint64 `json:"fromBlock"` + EffectiveTransmitterID null.String `json:"effectiveTransmitterID"` + ConfigContractAddress *common.Address `json:"configContractAddress"` // Contract-specific SendingKeys pq.StringArray `json:"sendingKeys"` diff --git a/core/services/relay/relay.go b/core/services/relay/relay.go index 96b12e52ba..96c3588002 100644 --- a/core/services/relay/relay.go +++ b/core/services/relay/relay.go @@ -134,8 +134,8 @@ func (r *relayerAdapter) Ready() (err error) { func (r *relayerAdapter) HealthReport() map[string]error { hr := make(map[string]error) - maps.Copy(r.Relayer.HealthReport(), hr) - maps.Copy(r.RelayerExt.HealthReport(), hr) + maps.Copy(hr, r.Relayer.HealthReport()) + maps.Copy(hr, r.RelayerExt.HealthReport()) return hr } diff --git a/core/services/s4/address_range.go b/core/services/s4/address_range.go index bd818798fa..679bb3b846 100644 --- a/core/services/s4/address_range.go +++ b/core/services/s4/address_range.go @@ -33,11 +33,14 @@ func NewFullAddressRange() *AddressRange { } // NewSingleAddressRange creates AddressRange for a single address. -func NewSingleAddressRange(address *utils.Big) *AddressRange { +func NewSingleAddressRange(address *utils.Big) (*AddressRange, error) { + if address == nil || address.Cmp(MinAddress) < 0 || address.Cmp(MaxAddress) > 0 { + return nil, errors.New("invalid address") + } return &AddressRange{ MinAddress: address, MaxAddress: address, - } + }, nil } // NewInitialAddressRangeForIntervals splits the full address space with intervals, @@ -75,14 +78,14 @@ func (r *AddressRange) Advance() { r.MinAddress = r.MinAddress.Add(interval) r.MaxAddress = r.MaxAddress.Add(interval) - if r.MaxAddress.Cmp(MaxAddress) > 0 { - r.MaxAddress = MaxAddress - } - if r.MinAddress.Cmp(MaxAddress) >= 0 { r.MinAddress = MinAddress r.MaxAddress = MinAddress.Add(interval).Sub(utils.NewBigI(1)) } + + if r.MaxAddress.Cmp(MaxAddress) > 0 { + r.MaxAddress = MaxAddress + } } // Contains returns true if the given address belongs to the range. diff --git a/core/services/s4/address_range_test.go b/core/services/s4/address_range_test.go index e276b45b57..bbd4d3baa5 100644 --- a/core/services/s4/address_range_test.go +++ b/core/services/s4/address_range_test.go @@ -27,7 +27,8 @@ func TestAddressRange_NewSingleAddressRange(t *testing.T) { t.Parallel() addr := utils.NewBigI(0x123) - sar := s4.NewSingleAddressRange(addr) + sar, err := s4.NewSingleAddressRange(addr) + assert.NoError(t, err) assert.Equal(t, addr, sar.MinAddress) assert.Equal(t, addr, sar.MaxAddress) assert.True(t, sar.Contains(addr)) diff --git a/core/services/s4/storage.go b/core/services/s4/storage.go index 2a2a4ffcdd..65aa2f4bab 100644 --- a/core/services/s4/storage.go +++ b/core/services/s4/storage.go @@ -98,7 +98,7 @@ func (s *storage) Get(ctx context.Context, key *Key) (*Record, *Metadata, error) return nil, nil, err } - if row.Expiration <= s.clock.Now().UnixMilli() { + if row.Version != key.Version || row.Expiration <= s.clock.Now().UnixMilli() { return nil, nil, ErrNotFound } @@ -119,7 +119,11 @@ func (s *storage) Get(ctx context.Context, key *Key) (*Record, *Metadata, error) func (s *storage) List(ctx context.Context, address common.Address) ([]*SnapshotRow, error) { bigAddress := utils.NewBig(address.Big()) - return s.orm.GetSnapshot(NewSingleAddressRange(bigAddress), pg.WithParentCtx(ctx)) + sar, err := NewSingleAddressRange(bigAddress) + if err != nil { + return nil, err + } + return s.orm.GetSnapshot(sar, pg.WithParentCtx(ctx)) } func (s *storage) Put(ctx context.Context, key *Key, record *Record, signature []byte) error { diff --git a/core/services/s4/storage_test.go b/core/services/s4/storage_test.go index 6c384d493b..11a8f6544c 100644 --- a/core/services/s4/storage_test.go +++ b/core/services/s4/storage_test.go @@ -217,7 +217,8 @@ func TestStorage_List(t *testing.T) { }, } - addressRange := s4.NewSingleAddressRange(utils.NewBig(address.Big())) + addressRange, err := s4.NewSingleAddressRange(utils.NewBig(address.Big())) + assert.NoError(t, err) ormMock.On("GetSnapshot", addressRange, mock.Anything).Return(ormRows, nil) rows, err := storage.List(testutils.Context(t), address) diff --git a/core/services/transmission/integration_test.go b/core/services/transmission/integration_test.go index 3aa025f0ae..0484b1d8cd 100644 --- a/core/services/transmission/integration_test.go +++ b/core/services/transmission/integration_test.go @@ -63,7 +63,7 @@ func deployTransmissionUniverse(t *testing.T) *EntryPointUniverse { holder1Key := cltest.MustGenerateRandomKey(t) t.Log("Holder key:", holder1Key.String()) - // Construct simulated blockchain environmnet. + // Construct simulated blockchain environment. holder1Transactor, err := bind.NewKeyedTransactorWithChainID(holder1Key.ToEcdsaPrivKey(), testutils.SimulatedChainID) require.NoError(t, err) var ( diff --git a/core/services/vrf/delegate.go b/core/services/vrf/delegate.go index cc6c05cacd..b5fe6cda76 100644 --- a/core/services/vrf/delegate.go +++ b/core/services/vrf/delegate.go @@ -20,7 +20,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_vrf_coordinator_v2" "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/gethwrappers/generated/vrf_coordinator_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_owner" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -94,7 +94,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC if err != nil { return nil, err } - coordinatorV2Plus, err := vrf_coordinator_v2plus.NewVRFCoordinatorV2Plus(jb.VRFSpec.CoordinatorAddress.Address(), chain.Client()) + coordinatorV2Plus, err := vrf_coordinator_v2_5.NewVRFCoordinatorV25(jb.VRFSpec.CoordinatorAddress.Address(), chain.Client()) if err != nil { return nil, err } @@ -144,11 +144,11 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC if vrfOwner != nil { return nil, errors.New("VRF Owner is not supported for VRF V2 Plus") } - linkEthFeedAddress, err := coordinatorV2Plus.LINKETHFEED(nil) + linkNativeFeedAddress, err := coordinatorV2Plus.LINKNATIVEFEED(nil) if err != nil { - return nil, errors.Wrap(err, "LINKETHFEED") + return nil, errors.Wrap(err, "LINKNATIVEFEED") } - aggregator, err := aggregator_v3_interface.NewAggregatorV3Interface(linkEthFeedAddress, chain.Client()) + aggregator, err := aggregator_v3_interface.NewAggregatorV3Interface(linkNativeFeedAddress, chain.Client()) if err != nil { return nil, errors.Wrap(err, "NewAggregatorV3Interface") } @@ -161,7 +161,7 @@ func (d *Delegate) ServicesForSpec(jb job.Job, qopts ...pg.QOpt) ([]job.ServiceC chain.ID(), chain.LogBroadcaster(), d.q, - v2.NewCoordinatorV2Plus(coordinatorV2Plus), + v2.NewCoordinatorV2_5(coordinatorV2Plus), batchCoordinatorV2, vrfOwner, aggregator, diff --git a/core/services/vrf/proof/proof_response.go b/core/services/vrf/proof/proof_response.go index 6d62e18a4f..4cb58d921a 100644 --- a/core/services/vrf/proof/proof_response.go +++ b/core/services/vrf/proof/proof_response.go @@ -7,7 +7,7 @@ import ( "math/big" "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/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/services/signatures/secp256k1" "github.com/ethereum/go-ethereum/common" @@ -138,11 +138,11 @@ func GenerateProofResponseFromProofV2(p vrfkey.Proof, s PreSeedDataV2) (vrf_coor func GenerateProofResponseFromProofV2Plus( p vrfkey.Proof, s PreSeedDataV2Plus) ( - vrf_coordinator_v2plus.VRFProof, - vrf_coordinator_v2plus.VRFCoordinatorV2PlusRequestCommitment, + vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof, + vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRequestCommitment, error) { - var proof vrf_coordinator_v2plus.VRFProof - var rc vrf_coordinator_v2plus.VRFCoordinatorV2PlusRequestCommitment + var proof vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof + var rc vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRequestCommitment solidityProof, err := SolidityPrecalculations(&p) if err != nil { return proof, rc, errors.Wrap(err, @@ -153,7 +153,7 @@ func GenerateProofResponseFromProofV2Plus( gx, gy := secp256k1.Coordinates(solidityProof.P.Gamma) cgx, cgy := secp256k1.Coordinates(solidityProof.CGammaWitness) shx, shy := secp256k1.Coordinates(solidityProof.SHashWitness) - return vrf_coordinator_v2plus.VRFProof{ + return vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof{ Pk: [2]*big.Int{x, y}, Gamma: [2]*big.Int{gx, gy}, C: solidityProof.P.C, @@ -163,7 +163,7 @@ func GenerateProofResponseFromProofV2Plus( CGammaWitness: [2]*big.Int{cgx, cgy}, SHashWitness: [2]*big.Int{shx, shy}, ZInv: solidityProof.ZInv, - }, vrf_coordinator_v2plus.VRFCoordinatorV2PlusRequestCommitment{ + }, vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRequestCommitment{ BlockNum: s.BlockNum, SubId: s.SubId, CallbackGasLimit: s.CallbackGasLimit, @@ -195,12 +195,12 @@ func GenerateProofResponseV2(keystore keystore.VRF, id string, s PreSeedDataV2) } func GenerateProofResponseV2Plus(keystore keystore.VRF, id string, s PreSeedDataV2Plus) ( - vrf_coordinator_v2plus.VRFProof, vrf_coordinator_v2plus.VRFCoordinatorV2PlusRequestCommitment, error) { + vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof, vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRequestCommitment, error) { seedHashMsg := append(s.PreSeed[:], s.BlockHash.Bytes()...) seed := utils.MustHash(string(seedHashMsg)).Big() proof, err := keystore.GenerateProof(id, seed) if err != nil { - return vrf_coordinator_v2plus.VRFProof{}, vrf_coordinator_v2plus.VRFCoordinatorV2PlusRequestCommitment{}, err + return vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof{}, vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRequestCommitment{}, err } return GenerateProofResponseFromProofV2Plus(proof, s) } diff --git a/core/services/vrf/v1/integration_test.go b/core/services/vrf/v1/integration_test.go index 0a57c72ef1..8626b43dd2 100644 --- a/core/services/vrf/v1/integration_test.go +++ b/core/services/vrf/v1/integration_test.go @@ -150,7 +150,7 @@ func TestIntegration_VRF_WithBHS(t *testing.T) { // Create BHS Job and start it bhsJob := vrftesthelpers.CreateAndStartBHSJob(t, sendingKeys, app, cu.BHSContractAddress.String(), - cu.RootContractAddress.String(), "", "", "", 0, 200) + cu.RootContractAddress.String(), "", "", "", 0, 200, 0, 100) // Ensure log poller is ready and has all logs. require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready()) diff --git a/core/services/vrf/v1/listener_v1.go b/core/services/vrf/v1/listener_v1.go index 39aec367b4..03b92bc15c 100644 --- a/core/services/vrf/v1/listener_v1.go +++ b/core/services/vrf/v1/listener_v1.go @@ -429,7 +429,7 @@ func (lsn *Listener) ProcessRequest(ctx context.Context, req request) bool { run := pipeline.NewRun(*lsn.Job.PipelineSpec, vars) // The VRF pipeline has no async tasks, so we don't need to check for `incomplete` - if _, err = lsn.PipelineRunner.Run(ctx, &run, lggr, true, func(tx pg.Queryer) error { + if _, err = lsn.PipelineRunner.Run(ctx, run, lggr, true, func(tx pg.Queryer) error { // Always mark consumed regardless of whether the proof failed or not. if err = lsn.LogBroadcaster.MarkConsumed(req.lb, pg.WithQueryer(tx)); err != nil { lggr.Errorw("Failed mark consumed", "err", err) diff --git a/core/services/vrf/v2/bhs_feeder_test.go b/core/services/vrf/v2/bhs_feeder_test.go new file mode 100644 index 0000000000..0da28378d0 --- /dev/null +++ b/core/services/vrf/v2/bhs_feeder_test.go @@ -0,0 +1,105 @@ +package v2_test + +import ( + "testing" + "time" + + "github.com/smartcontractkit/chainlink/v2/core/assets" + "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/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/vrf/vrfcommon" + "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrftesthelpers" + "github.com/smartcontractkit/chainlink/v2/core/store/models" + + "github.com/stretchr/testify/require" +) + +func TestStartHeartbeats(t *testing.T) { + t.Parallel() + ownerKey := cltest.MustGenerateRandomKey(t) + uni := newVRFCoordinatorV2Universe(t, ownerKey, 2) + + vrfKey := cltest.MustGenerateRandomKey(t) + sendEth(t, ownerKey, uni.backend, vrfKey.Address, 10) + gasLanePriceWei := assets.GWei(1) + gasLimit := 3_000_000 + + consumers := uni.vrfConsumers + + // generate n BHS keys to make sure BHS job rotates sending keys + var bhsKeyAddresses []string + var keySpecificOverrides []toml.KeySpecific + var keys []interface{} + for i := 0; i < len(consumers); i++ { + bhsKey := cltest.MustGenerateRandomKey(t) + bhsKeyAddresses = append(bhsKeyAddresses, bhsKey.Address.String()) + 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}, + }) + + keys = append(keys, ownerKey, vrfKey) + + config, _ := heavyweight.FullTestDBV2(t, "vrfv2_needs_blockhash_store", func(c *chainlink.Config, s *chainlink.Secrets) { + simulatedOverrides(t, gasLanePriceWei, 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].GasEstimator.LimitDefault = ptr(uint32(gasLimit)) + c.EVM[0].LogPollInterval = models.MustNewDuration(time.Second) + }) + + heartbeatPeriod := 5 * time.Second + + t.Run("bhs_feeder_startheartbeats_happy_path", func(tt *testing.T) { + coordinatorAddress := uni.rootContractAddress + vrfVersion := vrfcommon.V2 + + app := cltest.NewApplicationWithConfigV2AndKeyOnSimulatedBlockchain(t, config, uni.backend, keys...) + require.NoError(t, app.Start(testutils.Context(t))) + + var ( + v2CoordinatorAddress string + v2PlusCoordinatorAddress string + ) + + if vrfVersion == vrfcommon.V2 { + v2CoordinatorAddress = coordinatorAddress.String() + } else if vrfVersion == vrfcommon.V2Plus { + v2PlusCoordinatorAddress = coordinatorAddress.String() + } + + _ = vrftesthelpers.CreateAndStartBHSJob( + t, bhsKeyAddresses, app, uni.bhsContractAddress.String(), "", + v2CoordinatorAddress, v2PlusCoordinatorAddress, "", 0, 200, heartbeatPeriod, 100) + + // Ensure log poller is ready and has all logs. + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready()) + require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Replay(testutils.Context(t), 1)) + + initTxns := 260 + // Wait 260 blocks. + for i := 0; i < initTxns; i++ { + uni.backend.Commit() + } + diff := heartbeatPeriod + 1*time.Second + t.Logf("Sleeping %.2f seconds before checking blockhash in BHS added by BHS_Heartbeats_Service\n", diff.Seconds()) + time.Sleep(diff) + // storeEarliest in BHS contract stores blocktip - 256 in the Blockhash Store (BHS) + // before the initTxns:260 txns sent by the loop above, 18 txns are sent by + // newVRFCoordinatorV2Universe method. block tip is initTxns + 18 + blockTip := initTxns + 18 + verifyBlockhashStored(t, uni.coordinatorV2UniverseCommon, uint64(blockTip-256)) + }) +} diff --git a/core/services/vrf/v2/coordinator_v2x_interface.go b/core/services/vrf/v2/coordinator_v2x_interface.go index 8e2942ea92..b090c4ad5a 100644 --- a/core/services/vrf/v2/coordinator_v2x_interface.go +++ b/core/services/vrf/v2/coordinator_v2x_interface.go @@ -12,14 +12,15 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/chains/evm/log" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated" "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/gethwrappers/generated/vrf_coordinator_v2_5" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/extraargs" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" ) var ( _ CoordinatorV2_X = (*coordinatorV2)(nil) - _ CoordinatorV2_X = (*coordinatorV2Plus)(nil) + _ CoordinatorV2_X = (*coordinatorV2_5)(nil) ) // CoordinatorV2_X is an interface that allows us to use the same code for @@ -45,7 +46,7 @@ type CoordinatorV2_X interface { 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) + FundSubscriptionWithNative(opts *bind.TransactOpts, subID *big.Int, amount *big.Int) (*types.Transaction, error) } type coordinatorV2 struct { @@ -170,40 +171,40 @@ func (c *coordinatorV2) Migrate(opts *bind.TransactOpts, subID *big.Int, newCoor panic("migrate not implemented for v2") } -func (c *coordinatorV2) FundSubscriptionWithEth(opts *bind.TransactOpts, subID *big.Int, amount *big.Int) (*types.Transaction, error) { +func (c *coordinatorV2) FundSubscriptionWithNative(opts *bind.TransactOpts, subID *big.Int, amount *big.Int) (*types.Transaction, error) { panic("fund subscription with Eth not implemented for v2") } -type coordinatorV2Plus struct { +type coordinatorV2_5 struct { vrfVersion vrfcommon.Version - coordinator *vrf_coordinator_v2plus.VRFCoordinatorV2Plus + coordinator vrf_coordinator_v2_5.VRFCoordinatorV25Interface } -func NewCoordinatorV2Plus(c *vrf_coordinator_v2plus.VRFCoordinatorV2Plus) CoordinatorV2_X { - return &coordinatorV2Plus{ +func NewCoordinatorV2_5(c vrf_coordinator_v2_5.VRFCoordinatorV25Interface) CoordinatorV2_X { + return &coordinatorV2_5{ vrfVersion: vrfcommon.V2Plus, coordinator: c, } } -func (c *coordinatorV2Plus) Address() common.Address { +func (c *coordinatorV2_5) Address() common.Address { return c.coordinator.Address() } -func (c *coordinatorV2Plus) ParseRandomWordsRequested(log types.Log) (RandomWordsRequested, error) { +func (c *coordinatorV2_5) ParseRandomWordsRequested(log types.Log) (RandomWordsRequested, error) { parsed, err := c.coordinator.ParseRandomWordsRequested(log) if err != nil { return nil, err } - return NewV2PlusRandomWordsRequested(parsed), nil + return NewV2_5RandomWordsRequested(parsed), nil } -func (c *coordinatorV2Plus) RequestRandomWords(opts *bind.TransactOpts, keyHash [32]byte, subID *big.Int, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, payInEth bool) (*types.Transaction, error) { +func (c *coordinatorV2_5) RequestRandomWords(opts *bind.TransactOpts, keyHash [32]byte, subID *big.Int, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, payInEth bool) (*types.Transaction, error) { extraArgs, err := extraargs.ExtraArgsV1(payInEth) if err != nil { return nil, err } - req := vrf_coordinator_v2plus.VRFV2PlusClientRandomWordsRequest{ + req := vrf_coordinator_v2_5.VRFV2PlusClientRandomWordsRequest{ KeyHash: keyHash, SubId: subID, RequestConfirmations: requestConfirmations, @@ -214,41 +215,41 @@ func (c *coordinatorV2Plus) RequestRandomWords(opts *bind.TransactOpts, keyHash return c.coordinator.RequestRandomWords(opts, req) } -func (c *coordinatorV2Plus) AddConsumer(opts *bind.TransactOpts, subID *big.Int, consumer common.Address) (*types.Transaction, error) { +func (c *coordinatorV2_5) AddConsumer(opts *bind.TransactOpts, subID *big.Int, consumer common.Address) (*types.Transaction, error) { return c.coordinator.AddConsumer(opts, subID, consumer) } -func (c *coordinatorV2Plus) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { +func (c *coordinatorV2_5) CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) { return c.coordinator.CreateSubscription(opts) } -func (c *coordinatorV2Plus) GetSubscription(opts *bind.CallOpts, subID *big.Int) (Subscription, error) { +func (c *coordinatorV2_5) GetSubscription(opts *bind.CallOpts, subID *big.Int) (Subscription, error) { sub, err := c.coordinator.GetSubscription(opts, subID) if err != nil { return nil, err } - return NewV2PlusSubscription(sub), nil + return NewV2_5Subscription(sub), nil } -func (c *coordinatorV2Plus) GetConfig(opts *bind.CallOpts) (Config, error) { +func (c *coordinatorV2_5) GetConfig(opts *bind.CallOpts) (Config, error) { config, err := c.coordinator.SConfig(opts) if err != nil { return nil, err } - return NewV2PlusConfig(config), nil + return NewV2_5Config(config), nil } -func (c *coordinatorV2Plus) ParseLog(log types.Log) (generated.AbigenLog, error) { +func (c *coordinatorV2_5) ParseLog(log types.Log) (generated.AbigenLog, error) { return c.coordinator.ParseLog(log) } -func (c *coordinatorV2Plus) OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { +func (c *coordinatorV2_5) OracleWithdraw(opts *bind.TransactOpts, recipient common.Address, amount *big.Int) (*types.Transaction, error) { return c.coordinator.OracleWithdraw(opts, recipient, amount) } -func (c *coordinatorV2Plus) LogsWithTopics(keyHash common.Hash) map[common.Hash][][]log.Topic { +func (c *coordinatorV2_5) LogsWithTopics(keyHash common.Hash) map[common.Hash][][]log.Topic { return map[common.Hash][][]log.Topic{ - vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested{}.Topic(): { + vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested{}.Topic(): { { log.Topic(keyHash), }, @@ -256,70 +257,70 @@ func (c *coordinatorV2Plus) LogsWithTopics(keyHash common.Hash) map[common.Hash] } } -func (c *coordinatorV2Plus) Version() vrfcommon.Version { +func (c *coordinatorV2_5) Version() vrfcommon.Version { return c.vrfVersion } -func (c *coordinatorV2Plus) RegisterProvingKey(opts *bind.TransactOpts, oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) { +func (c *coordinatorV2_5) RegisterProvingKey(opts *bind.TransactOpts, oracle common.Address, publicProvingKey [2]*big.Int) (*types.Transaction, error) { return c.coordinator.RegisterProvingKey(opts, oracle, publicProvingKey) } -func (c *coordinatorV2Plus) FilterSubscriptionCreated(opts *bind.FilterOpts, subID []*big.Int) (SubscriptionCreatedIterator, error) { +func (c *coordinatorV2_5) FilterSubscriptionCreated(opts *bind.FilterOpts, subID []*big.Int) (SubscriptionCreatedIterator, error) { it, err := c.coordinator.FilterSubscriptionCreated(opts, subID) if err != nil { return nil, err } - return NewV2PlusSubscriptionCreatedIterator(it), nil + return NewV2_5SubscriptionCreatedIterator(it), nil } -func (c *coordinatorV2Plus) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subID []*big.Int, sender []common.Address) (RandomWordsRequestedIterator, error) { +func (c *coordinatorV2_5) FilterRandomWordsRequested(opts *bind.FilterOpts, keyHash [][32]byte, subID []*big.Int, sender []common.Address) (RandomWordsRequestedIterator, error) { it, err := c.coordinator.FilterRandomWordsRequested(opts, keyHash, subID, sender) if err != nil { return nil, err } - return NewV2PlusRandomWordsRequestedIterator(it), nil + return NewV2_5RandomWordsRequestedIterator(it), nil } -func (c *coordinatorV2Plus) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestID []*big.Int, subID []*big.Int) (RandomWordsFulfilledIterator, error) { +func (c *coordinatorV2_5) 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 } - return NewV2PlusRandomWordsFulfilledIterator(it), nil + return NewV2_5RandomWordsFulfilledIterator(it), nil } -func (c *coordinatorV2Plus) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { +func (c *coordinatorV2_5) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return c.coordinator.TransferOwnership(opts, to) } -func (c *coordinatorV2Plus) RemoveConsumer(opts *bind.TransactOpts, subID *big.Int, consumer common.Address) (*types.Transaction, error) { +func (c *coordinatorV2_5) RemoveConsumer(opts *bind.TransactOpts, subID *big.Int, consumer common.Address) (*types.Transaction, error) { return c.coordinator.RemoveConsumer(opts, subID, consumer) } -func (c *coordinatorV2Plus) CancelSubscription(opts *bind.TransactOpts, subID *big.Int, to common.Address) (*types.Transaction, error) { +func (c *coordinatorV2_5) CancelSubscription(opts *bind.TransactOpts, subID *big.Int, to common.Address) (*types.Transaction, error) { return c.coordinator.CancelSubscription(opts, subID, to) } -func (c *coordinatorV2Plus) GetCommitment(opts *bind.CallOpts, requestID *big.Int) ([32]byte, error) { +func (c *coordinatorV2_5) GetCommitment(opts *bind.CallOpts, requestID *big.Int) ([32]byte, error) { return c.coordinator.SRequestCommitments(opts, requestID) } -func (c *coordinatorV2Plus) Migrate(opts *bind.TransactOpts, subID *big.Int, newCoordinator common.Address) (*types.Transaction, error) { +func (c *coordinatorV2_5) 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) { +func (c *coordinatorV2_5) FundSubscriptionWithNative(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) + return c.coordinator.FundSubscriptionWithNative(&o, subID) } var ( _ RandomWordsRequestedIterator = (*v2RandomWordsRequestedIterator)(nil) - _ RandomWordsRequestedIterator = (*v2PlusRandomWordsRequestedIterator)(nil) + _ RandomWordsRequestedIterator = (*v2_5RandomWordsRequestedIterator)(nil) ) type RandomWordsRequestedIterator interface { @@ -357,37 +358,37 @@ func (it *v2RandomWordsRequestedIterator) Event() RandomWordsRequested { return NewV2RandomWordsRequested(it.iterator.Event) } -type v2PlusRandomWordsRequestedIterator struct { +type v2_5RandomWordsRequestedIterator struct { vrfVersion vrfcommon.Version - iterator *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequestedIterator + iterator *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequestedIterator } -func NewV2PlusRandomWordsRequestedIterator(it *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequestedIterator) RandomWordsRequestedIterator { - return &v2PlusRandomWordsRequestedIterator{ +func NewV2_5RandomWordsRequestedIterator(it *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequestedIterator) RandomWordsRequestedIterator { + return &v2_5RandomWordsRequestedIterator{ vrfVersion: vrfcommon.V2Plus, iterator: it, } } -func (it *v2PlusRandomWordsRequestedIterator) Next() bool { +func (it *v2_5RandomWordsRequestedIterator) Next() bool { return it.iterator.Next() } -func (it *v2PlusRandomWordsRequestedIterator) Error() error { +func (it *v2_5RandomWordsRequestedIterator) Error() error { return it.iterator.Error() } -func (it *v2PlusRandomWordsRequestedIterator) Close() error { +func (it *v2_5RandomWordsRequestedIterator) Close() error { return it.iterator.Close() } -func (it *v2PlusRandomWordsRequestedIterator) Event() RandomWordsRequested { - return NewV2PlusRandomWordsRequested(it.iterator.Event) +func (it *v2_5RandomWordsRequestedIterator) Event() RandomWordsRequested { + return NewV2_5RandomWordsRequested(it.iterator.Event) } var ( _ RandomWordsRequested = (*v2RandomWordsRequested)(nil) - _ RandomWordsRequested = (*v2PlusRandomWordsRequested)(nil) + _ RandomWordsRequested = (*v2_5RandomWordsRequested)(nil) ) type RandomWordsRequested interface { @@ -455,55 +456,55 @@ func (r *v2RandomWordsRequested) NativePayment() bool { return false } -type v2PlusRandomWordsRequested struct { +type v2_5RandomWordsRequested struct { vrfVersion vrfcommon.Version - event *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested + event *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested } -func NewV2PlusRandomWordsRequested(event *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested) RandomWordsRequested { - return &v2PlusRandomWordsRequested{ +func NewV2_5RandomWordsRequested(event *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested) RandomWordsRequested { + return &v2_5RandomWordsRequested{ vrfVersion: vrfcommon.V2Plus, event: event, } } -func (r *v2PlusRandomWordsRequested) Raw() types.Log { +func (r *v2_5RandomWordsRequested) Raw() types.Log { return r.event.Raw } -func (r *v2PlusRandomWordsRequested) NumWords() uint32 { +func (r *v2_5RandomWordsRequested) NumWords() uint32 { return r.event.NumWords } -func (r *v2PlusRandomWordsRequested) SubID() *big.Int { +func (r *v2_5RandomWordsRequested) SubID() *big.Int { return r.event.SubId } -func (r *v2PlusRandomWordsRequested) MinimumRequestConfirmations() uint16 { +func (r *v2_5RandomWordsRequested) MinimumRequestConfirmations() uint16 { return r.event.MinimumRequestConfirmations } -func (r *v2PlusRandomWordsRequested) KeyHash() [32]byte { +func (r *v2_5RandomWordsRequested) KeyHash() [32]byte { return r.event.KeyHash } -func (r *v2PlusRandomWordsRequested) RequestID() *big.Int { +func (r *v2_5RandomWordsRequested) RequestID() *big.Int { return r.event.RequestId } -func (r *v2PlusRandomWordsRequested) PreSeed() *big.Int { +func (r *v2_5RandomWordsRequested) PreSeed() *big.Int { return r.event.PreSeed } -func (r *v2PlusRandomWordsRequested) Sender() common.Address { +func (r *v2_5RandomWordsRequested) Sender() common.Address { return r.event.Sender } -func (r *v2PlusRandomWordsRequested) CallbackGasLimit() uint32 { +func (r *v2_5RandomWordsRequested) CallbackGasLimit() uint32 { return r.event.CallbackGasLimit } -func (r *v2PlusRandomWordsRequested) NativePayment() bool { +func (r *v2_5RandomWordsRequested) NativePayment() bool { nativePayment, err := extraargs.FromExtraArgsV1(r.event.ExtraArgs) if err != nil { panic(err) @@ -513,7 +514,7 @@ func (r *v2PlusRandomWordsRequested) NativePayment() bool { var ( _ RandomWordsFulfilledIterator = (*v2RandomWordsFulfilledIterator)(nil) - _ RandomWordsFulfilledIterator = (*v2PlusRandomWordsFulfilledIterator)(nil) + _ RandomWordsFulfilledIterator = (*v2_5RandomWordsFulfilledIterator)(nil) ) type RandomWordsFulfilledIterator interface { @@ -551,37 +552,37 @@ func (it *v2RandomWordsFulfilledIterator) Event() RandomWordsFulfilled { return NewV2RandomWordsFulfilled(it.iterator.Event) } -type v2PlusRandomWordsFulfilledIterator struct { +type v2_5RandomWordsFulfilledIterator struct { vrfVersion vrfcommon.Version - iterator *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilledIterator + iterator *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilledIterator } -func NewV2PlusRandomWordsFulfilledIterator(it *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilledIterator) RandomWordsFulfilledIterator { - return &v2PlusRandomWordsFulfilledIterator{ +func NewV2_5RandomWordsFulfilledIterator(it *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilledIterator) RandomWordsFulfilledIterator { + return &v2_5RandomWordsFulfilledIterator{ vrfVersion: vrfcommon.V2Plus, iterator: it, } } -func (it *v2PlusRandomWordsFulfilledIterator) Next() bool { +func (it *v2_5RandomWordsFulfilledIterator) Next() bool { return it.iterator.Next() } -func (it *v2PlusRandomWordsFulfilledIterator) Error() error { +func (it *v2_5RandomWordsFulfilledIterator) Error() error { return it.iterator.Error() } -func (it *v2PlusRandomWordsFulfilledIterator) Close() error { +func (it *v2_5RandomWordsFulfilledIterator) Close() error { return it.iterator.Close() } -func (it *v2PlusRandomWordsFulfilledIterator) Event() RandomWordsFulfilled { - return NewV2PlusRandomWordsFulfilled(it.iterator.Event) +func (it *v2_5RandomWordsFulfilledIterator) Event() RandomWordsFulfilled { + return NewV2_5RandomWordsFulfilled(it.iterator.Event) } var ( _ RandomWordsFulfilled = (*v2RandomWordsFulfilled)(nil) - _ RandomWordsFulfilled = (*v2PlusRandomWordsFulfilled)(nil) + _ RandomWordsFulfilled = (*v2_5RandomWordsFulfilled)(nil) ) type RandomWordsFulfilled interface { @@ -628,41 +629,41 @@ func (rwf *v2RandomWordsFulfilled) Raw() types.Log { return rwf.event.Raw } -type v2PlusRandomWordsFulfilled struct { +type v2_5RandomWordsFulfilled struct { vrfVersion vrfcommon.Version - event *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled + event *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled } -func NewV2PlusRandomWordsFulfilled(event *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled) RandomWordsFulfilled { - return &v2PlusRandomWordsFulfilled{ +func NewV2_5RandomWordsFulfilled(event *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled) RandomWordsFulfilled { + return &v2_5RandomWordsFulfilled{ vrfVersion: vrfcommon.V2Plus, event: event, } } -func (rwf *v2PlusRandomWordsFulfilled) RequestID() *big.Int { +func (rwf *v2_5RandomWordsFulfilled) RequestID() *big.Int { return rwf.event.RequestId } -func (rwf *v2PlusRandomWordsFulfilled) Success() bool { +func (rwf *v2_5RandomWordsFulfilled) Success() bool { return rwf.event.Success } -func (rwf *v2PlusRandomWordsFulfilled) SubID() *big.Int { - return rwf.event.SubID +func (rwf *v2_5RandomWordsFulfilled) SubID() *big.Int { + return rwf.event.SubId } -func (rwf *v2PlusRandomWordsFulfilled) Payment() *big.Int { +func (rwf *v2_5RandomWordsFulfilled) Payment() *big.Int { return rwf.event.Payment } -func (rwf *v2PlusRandomWordsFulfilled) Raw() types.Log { +func (rwf *v2_5RandomWordsFulfilled) Raw() types.Log { return rwf.event.Raw } var ( _ SubscriptionCreatedIterator = (*v2SubscriptionCreatedIterator)(nil) - _ SubscriptionCreatedIterator = (*v2PlusSubscriptionCreatedIterator)(nil) + _ SubscriptionCreatedIterator = (*v2_5SubscriptionCreatedIterator)(nil) ) type SubscriptionCreatedIterator interface { @@ -700,37 +701,37 @@ func (it *v2SubscriptionCreatedIterator) Event() SubscriptionCreated { return NewV2SubscriptionCreated(it.iterator.Event) } -type v2PlusSubscriptionCreatedIterator struct { +type v2_5SubscriptionCreatedIterator struct { vrfVersion vrfcommon.Version - iterator *vrf_coordinator_v2plus.VRFCoordinatorV2PlusSubscriptionCreatedIterator + iterator *vrf_coordinator_v2_5.VRFCoordinatorV25SubscriptionCreatedIterator } -func NewV2PlusSubscriptionCreatedIterator(it *vrf_coordinator_v2plus.VRFCoordinatorV2PlusSubscriptionCreatedIterator) SubscriptionCreatedIterator { - return &v2PlusSubscriptionCreatedIterator{ +func NewV2_5SubscriptionCreatedIterator(it *vrf_coordinator_v2_5.VRFCoordinatorV25SubscriptionCreatedIterator) SubscriptionCreatedIterator { + return &v2_5SubscriptionCreatedIterator{ vrfVersion: vrfcommon.V2Plus, iterator: it, } } -func (it *v2PlusSubscriptionCreatedIterator) Next() bool { +func (it *v2_5SubscriptionCreatedIterator) Next() bool { return it.iterator.Next() } -func (it *v2PlusSubscriptionCreatedIterator) Error() error { +func (it *v2_5SubscriptionCreatedIterator) Error() error { return it.iterator.Error() } -func (it *v2PlusSubscriptionCreatedIterator) Close() error { +func (it *v2_5SubscriptionCreatedIterator) Close() error { return it.iterator.Close() } -func (it *v2PlusSubscriptionCreatedIterator) Event() SubscriptionCreated { - return NewV2PlusSubscriptionCreated(it.iterator.Event) +func (it *v2_5SubscriptionCreatedIterator) Event() SubscriptionCreated { + return NewV2_5SubscriptionCreated(it.iterator.Event) } var ( _ SubscriptionCreated = (*v2SubscriptionCreated)(nil) - _ SubscriptionCreated = (*v2PlusSubscriptionCreated)(nil) + _ SubscriptionCreated = (*v2_5SubscriptionCreated)(nil) ) type SubscriptionCreated interface { @@ -758,34 +759,34 @@ func (sc *v2SubscriptionCreated) SubID() *big.Int { return new(big.Int).SetUint64(sc.event.SubId) } -type v2PlusSubscriptionCreated struct { +type v2_5SubscriptionCreated struct { vrfVersion vrfcommon.Version - event *vrf_coordinator_v2plus.VRFCoordinatorV2PlusSubscriptionCreated + event *vrf_coordinator_v2_5.VRFCoordinatorV25SubscriptionCreated } -func NewV2PlusSubscriptionCreated(event *vrf_coordinator_v2plus.VRFCoordinatorV2PlusSubscriptionCreated) SubscriptionCreated { - return &v2PlusSubscriptionCreated{ +func NewV2_5SubscriptionCreated(event *vrf_coordinator_v2_5.VRFCoordinatorV25SubscriptionCreated) SubscriptionCreated { + return &v2_5SubscriptionCreated{ vrfVersion: vrfcommon.V2Plus, event: event, } } -func (sc *v2PlusSubscriptionCreated) Owner() common.Address { +func (sc *v2_5SubscriptionCreated) Owner() common.Address { return sc.event.Owner } -func (sc *v2PlusSubscriptionCreated) SubID() *big.Int { +func (sc *v2_5SubscriptionCreated) SubID() *big.Int { return sc.event.SubId } var ( _ Subscription = (*v2Subscription)(nil) - _ Subscription = (*v2PlusSubscription)(nil) + _ Subscription = (*v2_5Subscription)(nil) ) type Subscription interface { Balance() *big.Int - EthBalance() *big.Int + NativeBalance() *big.Int Owner() common.Address Consumers() []common.Address Version() vrfcommon.Version @@ -807,7 +808,7 @@ func (s v2Subscription) Balance() *big.Int { return s.event.Balance } -func (s v2Subscription) EthBalance() *big.Int { +func (s v2Subscription) NativeBalance() *big.Int { panic("EthBalance not supported on V2") } @@ -823,41 +824,41 @@ func (s v2Subscription) Version() vrfcommon.Version { return s.vrfVersion } -type v2PlusSubscription struct { +type v2_5Subscription struct { vrfVersion vrfcommon.Version - event vrf_coordinator_v2plus.GetSubscription + event vrf_coordinator_v2_5.GetSubscription } -func NewV2PlusSubscription(event vrf_coordinator_v2plus.GetSubscription) Subscription { - return &v2PlusSubscription{ +func NewV2_5Subscription(event vrf_coordinator_v2_5.GetSubscription) Subscription { + return &v2_5Subscription{ vrfVersion: vrfcommon.V2Plus, event: event, } } -func (s *v2PlusSubscription) Balance() *big.Int { +func (s *v2_5Subscription) Balance() *big.Int { return s.event.Balance } -func (s *v2PlusSubscription) EthBalance() *big.Int { - return s.event.EthBalance +func (s *v2_5Subscription) NativeBalance() *big.Int { + return s.event.NativeBalance } -func (s *v2PlusSubscription) Owner() common.Address { +func (s *v2_5Subscription) Owner() common.Address { return s.event.Owner } -func (s *v2PlusSubscription) Consumers() []common.Address { +func (s *v2_5Subscription) Consumers() []common.Address { return s.event.Consumers } -func (s *v2PlusSubscription) Version() vrfcommon.Version { +func (s *v2_5Subscription) Version() vrfcommon.Version { return s.vrfVersion } var ( _ Config = (*v2Config)(nil) - _ Config = (*v2PlusConfig)(nil) + _ Config = (*v2_5Config)(nil) ) type Config interface { @@ -895,38 +896,38 @@ func (c *v2Config) StalenessSeconds() uint32 { return c.config.StalenessSeconds } -type v2PlusConfig struct { +type v2_5Config struct { vrfVersion vrfcommon.Version - config vrf_coordinator_v2plus.SConfig + config vrf_coordinator_v2_5.SConfig } -func NewV2PlusConfig(config vrf_coordinator_v2plus.SConfig) Config { - return &v2PlusConfig{ +func NewV2_5Config(config vrf_coordinator_v2_5.SConfig) Config { + return &v2_5Config{ vrfVersion: vrfcommon.V2Plus, config: config, } } -func (c *v2PlusConfig) MinimumRequestConfirmations() uint16 { +func (c *v2_5Config) MinimumRequestConfirmations() uint16 { return c.config.MinimumRequestConfirmations } -func (c *v2PlusConfig) MaxGasLimit() uint32 { +func (c *v2_5Config) MaxGasLimit() uint32 { return c.config.MaxGasLimit } -func (c *v2PlusConfig) GasAfterPaymentCalculation() uint32 { +func (c *v2_5Config) GasAfterPaymentCalculation() uint32 { return c.config.GasAfterPaymentCalculation } -func (c *v2PlusConfig) StalenessSeconds() uint32 { +func (c *v2_5Config) StalenessSeconds() uint32 { return c.config.StalenessSeconds } type VRFProof struct { VRFVersion vrfcommon.Version V2 vrf_coordinator_v2.VRFProof - V2Plus vrf_coordinator_v2plus.VRFProof + V2Plus vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof } func FromV2Proof(proof vrf_coordinator_v2.VRFProof) VRFProof { @@ -936,7 +937,7 @@ func FromV2Proof(proof vrf_coordinator_v2.VRFProof) VRFProof { } } -func FromV2PlusProof(proof vrf_coordinator_v2plus.VRFProof) VRFProof { +func FromV2PlusProof(proof vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof) VRFProof { return VRFProof{ VRFVersion: vrfcommon.V2Plus, V2Plus: proof, @@ -951,8 +952,8 @@ func ToV2Proofs(proofs []VRFProof) []vrf_coordinator_v2.VRFProof { return v2Proofs } -func ToV2PlusProofs(proofs []VRFProof) []vrf_coordinator_v2plus.VRFProof { - v2Proofs := make([]vrf_coordinator_v2plus.VRFProof, len(proofs)) +func ToV2PlusProofs(proofs []VRFProof) []vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof { + v2Proofs := make([]vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof, len(proofs)) for i, proof := range proofs { v2Proofs[i] = proof.V2Plus } @@ -962,7 +963,7 @@ func ToV2PlusProofs(proofs []VRFProof) []vrf_coordinator_v2plus.VRFProof { type RequestCommitment struct { VRFVersion vrfcommon.Version V2 vrf_coordinator_v2.VRFCoordinatorV2RequestCommitment - V2Plus vrf_coordinator_v2plus.VRFCoordinatorV2PlusRequestCommitment + V2Plus vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRequestCommitment } func ToV2Commitments(commitments []RequestCommitment) []vrf_coordinator_v2.VRFCoordinatorV2RequestCommitment { @@ -973,8 +974,8 @@ func ToV2Commitments(commitments []RequestCommitment) []vrf_coordinator_v2.VRFCo return v2Commitments } -func ToV2PlusCommitments(commitments []RequestCommitment) []vrf_coordinator_v2plus.VRFCoordinatorV2PlusRequestCommitment { - v2PlusCommitments := make([]vrf_coordinator_v2plus.VRFCoordinatorV2PlusRequestCommitment, len(commitments)) +func ToV2PlusCommitments(commitments []RequestCommitment) []vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRequestCommitment { + v2PlusCommitments := make([]vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRequestCommitment, len(commitments)) for i, commitment := range commitments { v2PlusCommitments[i] = commitment.V2Plus } @@ -985,7 +986,7 @@ func NewRequestCommitment(val any) RequestCommitment { switch val := val.(type) { case vrf_coordinator_v2.VRFCoordinatorV2RequestCommitment: return RequestCommitment{VRFVersion: vrfcommon.V2, V2: val} - case vrf_coordinator_v2plus.VRFCoordinatorV2PlusRequestCommitment: + case vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRequestCommitment: return RequestCommitment{VRFVersion: vrfcommon.V2Plus, V2Plus: val} default: panic(fmt.Sprintf("NewRequestCommitment: unknown type %T", val)) diff --git a/core/services/vrf/v2/integration_helpers_test.go b/core/services/vrf/v2/integration_helpers_test.go index 74d7175e08..262ac7ef48 100644 --- a/core/services/vrf/v2/integration_helpers_test.go +++ b/core/services/vrf/v2/integration_helpers_test.go @@ -241,7 +241,7 @@ func testMultipleConsumersNeedBHS( _ = vrftesthelpers.CreateAndStartBHSJob( t, bhsKeyAddresses, app, uni.bhsContractAddress.String(), "", - v2CoordinatorAddress, v2PlusCoordinatorAddress, "", 0, 200) + v2CoordinatorAddress, v2PlusCoordinatorAddress, "", 0, 200, 0, 100) // Ensure log poller is ready and has all logs. require.NoError(t, app.GetRelayers().LegacyEVMChains().Slice()[0].LogPoller().Ready()) @@ -350,6 +350,7 @@ func testMultipleConsumersNeedTrustedBHS( 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.EVM[0].GasEstimator.LimitDefault = ptr(uint32(5_000_000)) c.Feature.LogPoller = ptr(true) c.EVM[0].FinalityDepth = ptr[uint32](2) c.EVM[0].LogPollInterval = models.MustNewDuration(time.Second) @@ -384,9 +385,13 @@ func testMultipleConsumersNeedTrustedBHS( v2PlusCoordinatorAddress = coordinatorAddress.String() } + waitBlocks := 100 + if addedDelay { + waitBlocks = 400 + } _ = vrftesthelpers.CreateAndStartBHSJob( t, bhsKeyAddressesStrings, app, "", "", - v2CoordinatorAddress, v2PlusCoordinatorAddress, uni.trustedBhsContractAddress.String(), 20, 1000) + v2CoordinatorAddress, v2PlusCoordinatorAddress, uni.trustedBhsContractAddress.String(), 20, 1000, 0, waitBlocks) // Ensure log poller is ready and has all logs. chain := app.GetRelayers().LegacyEVMChains().Slice()[0] diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go index 8923bfac64..2f20842aa5 100644 --- a/core/services/vrf/v2/integration_v2_plus_test.go +++ b/core/services/vrf/v2/integration_v2_plus_test.go @@ -28,8 +28,9 @@ import ( "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_5" "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_coordinator_v2plus_interface" "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" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_sub_owner" @@ -104,7 +105,7 @@ func newVRFCoordinatorV2PlusUniverse(t *testing.T, key ethkey.KeyV2, numConsumer vrfv2plus_consumer_example.VRFV2PlusConsumerExampleABI)) require.NoError(t, err) coordinatorABI, err := abi.JSON(strings.NewReader( - vrf_coordinator_v2plus.VRFCoordinatorV2PlusABI)) + vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalABI)) require.NoError(t, err) backend := cltest.NewSimulatedBackend(t, genesisData, gasLimit) // Deploy link @@ -136,12 +137,12 @@ func newVRFCoordinatorV2PlusUniverse(t *testing.T, key ethkey.KeyV2, numConsumer bhsAddr = trustedBHSAddress } coordinatorAddress, _, coordinatorContract, err := - vrf_coordinator_v2plus.DeployVRFCoordinatorV2Plus( + vrf_coordinator_v2_5.DeployVRFCoordinatorV25( neil, backend, bhsAddr) require.NoError(t, err, "failed to deploy VRFCoordinatorV2 contract to simulated ethereum blockchain") backend.Commit() - _, err = coordinatorContract.SetLINKAndLINKETHFeed(neil, linkAddress, linkEthFeed) + _, err = coordinatorContract.SetLINKAndLINKNativeFeed(neil, linkAddress, linkEthFeed) require.NoError(t, err) backend.Commit() @@ -251,9 +252,9 @@ func newVRFCoordinatorV2PlusUniverse(t *testing.T, key ethkey.KeyV2, numConsumer uint32(60*60*24), // stalenessSeconds uint32(v22.GasAfterPaymentCalculation), // gasAfterPaymentCalculation big.NewInt(1e16), // 0.01 eth per link fallbackLinkPrice - vrf_coordinator_v2plus.VRFCoordinatorV2PlusFeeConfig{ - FulfillmentFlatFeeLinkPPM: uint32(1000), // 0.001 LINK premium - FulfillmentFlatFeeEthPPM: uint32(5), // 0.000005 ETH preimum + vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig{ + FulfillmentFlatFeeLinkPPM: uint32(1000), // 0.001 LINK premium + FulfillmentFlatFeeNativePPM: uint32(5), // 0.000005 ETH premium }, ) require.NoError(t, err, "failed to set coordinator configuration") @@ -272,7 +273,7 @@ func newVRFCoordinatorV2PlusUniverse(t *testing.T, key ethkey.KeyV2, numConsumer consumerProxyContractAddress: proxiedConsumer.Address(), proxyAdminAddress: proxyAdminAddress, - rootContract: v22.NewCoordinatorV2Plus(coordinatorContract), + rootContract: v22.NewCoordinatorV2_5(coordinatorContract), rootContractAddress: coordinatorAddress, linkContract: linkContract, linkContractAddress: linkAddress, @@ -717,16 +718,16 @@ func TestVRFV2PlusIntegration_ExternalOwnerConsumerExample(t *testing.T) { require.NoError(t, err) backend.Commit() coordinatorAddress, _, coordinator, err := - vrf_coordinator_v2plus.DeployVRFCoordinatorV2Plus( + vrf_coordinator_v2_5.DeployVRFCoordinatorV25( owner, backend, common.Address{}) //bhs not needed for this test require.NoError(t, err) - _, err = coordinator.SetConfig(owner, uint16(1), uint32(10000), 1, 1, big.NewInt(10), vrf_coordinator_v2plus.VRFCoordinatorV2PlusFeeConfig{ - FulfillmentFlatFeeLinkPPM: 0, - FulfillmentFlatFeeEthPPM: 0, + _, err = coordinator.SetConfig(owner, uint16(1), uint32(10000), 1, 1, big.NewInt(10), vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig{ + FulfillmentFlatFeeLinkPPM: 0, + FulfillmentFlatFeeNativePPM: 0, }) require.NoError(t, err) backend.Commit() - _, err = coordinator.SetLINKAndLINKETHFeed(owner, linkAddress, linkEthFeed) + _, err = coordinator.SetLINKAndLINKNativeFeed(owner, linkAddress, linkEthFeed) require.NoError(t, err) backend.Commit() consumerAddress, _, consumer, err := vrf_v2plus_sub_owner.DeployVRFV2PlusExternalSubOwnerExample(owner, backend, coordinatorAddress, linkAddress) @@ -787,11 +788,11 @@ func TestVRFV2PlusIntegration_SimpleConsumerExample(t *testing.T) { require.NoError(t, err) backend.Commit() coordinatorAddress, _, coordinator, err := - vrf_coordinator_v2plus.DeployVRFCoordinatorV2Plus( + vrf_coordinator_v2_5.DeployVRFCoordinatorV25( owner, backend, common.Address{}) // bhs not needed for this test require.NoError(t, err) backend.Commit() - _, err = coordinator.SetLINKAndLINKETHFeed(owner, linkAddress, linkEthFeed) + _, err = coordinator.SetLINKAndLINKNativeFeed(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) @@ -1137,7 +1138,7 @@ func setupSubscriptionAndFund( require.NoError(t, err, "failed to fund sub") uni.backend.Commit() - _, err = uni.rootContract.FundSubscriptionWithEth(consumer, subID, nativeAmount) + _, err = uni.rootContract.FundSubscriptionWithNative(consumer, subID, nativeAmount) require.NoError(t, err, "failed to fund sub with native") uni.backend.Commit() @@ -1238,12 +1239,12 @@ func TestVRFV2PlusIntegration_Migration(t *testing.T) { require.NoError(t, err) require.Equal(t, subV1.Balance(), totalLinkBalance) - require.Equal(t, subV1.EthBalance(), totalNativeBalance) + require.Equal(t, subV1.NativeBalance(), totalNativeBalance) require.Equal(t, subV1.Balance(), linkContractBalance) - require.Equal(t, subV1.EthBalance(), balance) + require.Equal(t, subV1.NativeBalance(), balance) require.Equal(t, subV1.Balance(), subV2.LinkBalance) - require.Equal(t, subV1.EthBalance(), subV2.NativeBalance) + require.Equal(t, subV1.NativeBalance(), subV2.NativeBalance) require.Equal(t, subV1.Owner(), subV2.Owner) require.Equal(t, len(subV1.Consumers()), len(subV2.Consumers)) for i, c := range subV1.Consumers() { diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index f405433380..531c7ebb66 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -497,7 +497,7 @@ func subscribeVRF( require.NoError(t, err) if nativePayment { - require.Equal(t, fundingAmount.String(), sub.EthBalance().String()) + require.Equal(t, fundingAmount.String(), sub.NativeBalance().String()) } else { require.Equal(t, fundingAmount.String(), sub.Balance().String()) } @@ -803,7 +803,7 @@ func mineBatch(t *testing.T, requestIDs []*big.Int, subID *big.Int, backend *bac require.NoError(t, err) for _, tx := range txs { var evmTx txmgr.Tx - txmgr.DbEthTxToEthTx(tx, &evmTx) + tx.ToTx(&evmTx) meta, err := evmTx.GetMeta() require.NoError(t, err) for _, requestID := range meta.RequestIDs { @@ -1320,7 +1320,6 @@ func TestVRFV2Integration_SingleConsumer_NeedsTrustedBlockhashStore(t *testing.T } func TestVRFV2Integration_SingleConsumer_NeedsTrustedBlockhashStore_AfterDelay(t *testing.T) { - t.Skip("TODO: VRF-616") t.Parallel() ownerKey := cltest.MustGenerateRandomKey(t) uni := newVRFCoordinatorV2PlusUniverse(t, ownerKey, 2, true) @@ -2105,7 +2104,8 @@ func TestStartingCountsV1(t *testing.T) { sql := `INSERT INTO evm.txes (nonce, from_address, to_address, encoded_payload, value, gas_limit, state, created_at, broadcast_at, initial_broadcast_at, meta, subject, evm_chain_id, min_confirmations, pipeline_task_run_id) VALUES (:nonce, :from_address, :to_address, :encoded_payload, :value, :gas_limit, :state, :created_at, :broadcast_at, :initial_broadcast_at, :meta, :subject, :evm_chain_id, :min_confirmations, :pipeline_task_run_id);` for _, tx := range append(confirmedTxes, unconfirmedTxes...) { - dbEtx := txmgr.DbEthTxFromEthTx(&tx) + var dbEtx txmgr.DbEthTx + dbEtx.FromTx(&tx) //nolint:gosec // just copying fields _, err = db.NamedExec(sql, &dbEtx) require.NoError(t, err) } @@ -2143,10 +2143,10 @@ VALUES (:nonce, :from_address, :to_address, :encoded_payload, :value, :gas_limit sql = `INSERT INTO evm.tx_attempts (eth_tx_id, gas_price, signed_raw_tx, hash, state, created_at, chain_specific_gas_limit) VALUES (:eth_tx_id, :gas_price, :signed_raw_tx, :hash, :state, :created_at, :chain_specific_gas_limit)` for _, attempt := range txAttempts { - dbAttempt := txmgr.DbEthTxAttemptFromEthTxAttempt(&attempt) //nolint:gosec // just copying fields + var dbAttempt txmgr.DbEthTxAttempt + dbAttempt.FromTxAttempt(&attempt) //nolint:gosec // just copying fields _, err = db.NamedExec(sql, &dbAttempt) require.NoError(t, err) - txmgr.DbEthTxAttemptToEthTxAttempt(dbAttempt, &attempt) //nolint:gosec // just copying fields } // add evm.receipts @@ -2164,7 +2164,7 @@ VALUES (:nonce, :from_address, :to_address, :encoded_payload, :value, :gas_limit sql = `INSERT INTO evm.receipts (block_hash, tx_hash, block_number, transaction_index, receipt, created_at) VALUES (:block_hash, :tx_hash, :block_number, :transaction_index, :receipt, :created_at)` for _, r := range receipts { - _, err := db.NamedExec(sql, &r) + _, err := db.NamedExec(sql, r) require.NoError(t, err) } diff --git a/core/services/vrf/v2/listener_v2.go b/core/services/vrf/v2/listener_v2.go index 047a1e6e29..6a1ad3e8b2 100644 --- a/core/services/vrf/v2/listener_v2.go +++ b/core/services/vrf/v2/listener_v2.go @@ -34,7 +34,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_vrf_coordinator_v2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/batch_vrf_coordinator_v2plus" "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/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_owner" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/services/job" @@ -50,7 +50,7 @@ var ( _ log.Listener = &listenerV2{} _ job.ServiceCtx = &listenerV2{} coordinatorV2ABI = evmtypes.MustGetABI(vrf_coordinator_v2.VRFCoordinatorV2ABI) - coordinatorV2PlusABI = evmtypes.MustGetABI(vrf_coordinator_v2plus.VRFCoordinatorV2PlusABI) + coordinatorV2PlusABI = evmtypes.MustGetABI(vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalABI) batchCoordinatorV2ABI = evmtypes.MustGetABI(batch_vrf_coordinator_v2.BatchVRFCoordinatorV2ABI) batchCoordinatorV2PlusABI = evmtypes.MustGetABI(batch_vrf_coordinator_v2plus.BatchVRFCoordinatorV2PlusABI) vrfOwnerABI = evmtypes.MustGetABI(vrf_owner.VRFOwnerMetaData.ABI) @@ -181,7 +181,7 @@ type vrfPipelineResult struct { // fundsNeeded indicates a "minimum balance" in juels or wei that must be held in the // subscription's account in order to fulfill the request. fundsNeeded *big.Int - run pipeline.Run + run *pipeline.Run payload string gasLimit uint32 req pendingRequest @@ -493,7 +493,7 @@ func (lsn *listenerV2) processPendingVRFRequests(ctx context.Context) { // Happy path - sub is active. startLinkBalance = sub.Balance() if sub.Version() == vrfcommon.V2Plus { - startEthBalance = sub.EthBalance() + startEthBalance = sub.NativeBalance() } subIsActive = true } @@ -1098,7 +1098,7 @@ func (lsn *listenerV2) processRequestsPerSubHelper( ll.Infow("Enqueuing fulfillment") var transaction txmgr.Tx err = lsn.q.Transaction(func(tx pg.Queryer) error { - if err = lsn.pipelineRunner.InsertFinishedRun(&p.run, true, pg.WithQueryer(tx)); err != nil { + if err = lsn.pipelineRunner.InsertFinishedRun(p.run, true, pg.WithQueryer(tx)); err != nil { return err } if err = lsn.logBroadcaster.MarkConsumed(p.req.lb, pg.WithQueryer(tx)); err != nil { @@ -1496,7 +1496,7 @@ func (lsn *listenerV2) simulateFulfillment( if trr.Task.Type() == pipeline.TaskTypeVRFV2Plus { m := trr.Result.Value.(map[string]interface{}) res.payload = m["output"].(string) - res.proof = FromV2PlusProof(m["proof"].(vrf_coordinator_v2plus.VRFProof)) + res.proof = FromV2PlusProof(m["proof"].(vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalProof)) res.reqCommitment = NewRequestCommitment(m["requestCommitment"]) } @@ -1598,7 +1598,7 @@ func (lsn *listenerV2) handleLog(lb log.Broadcast, minConfs uint32) { return } - if v, ok := lb.DecodedLog().(*vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled); ok { + if v, ok := lb.DecodedLog().(*vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRandomWordsFulfilled); ok { lsn.l.Debugw("Received fulfilled log", "reqID", v.RequestId, "success", v.Success) consumed, err := lsn.logBroadcaster.WasAlreadyConsumed(lb) if err != nil { diff --git a/core/services/vrf/v2/listener_v2_test.go b/core/services/vrf/v2/listener_v2_test.go index 4da20a2a7e..77e279d8f7 100644 --- a/core/services/vrf/v2/listener_v2_test.go +++ b/core/services/vrf/v2/listener_v2_test.go @@ -16,7 +16,7 @@ import ( "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/gethwrappers/generated/vrf_coordinator_v2plus_interface" "github.com/smartcontractkit/chainlink/v2/core/services/job" "github.com/smartcontractkit/chainlink/v2/core/services/vrf/vrfcommon" @@ -468,7 +468,7 @@ func TestListener_handleLog(tt *testing.T) { FromAddresses: []string{"0xF2982b7Ef6E3D8BB738f8Ea20502229781f6Ad97"}, }).Toml()) require.NoError(t, err) - fulfilledLog := vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled{ + fulfilledLog := vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalRandomWordsFulfilled{ RequestId: big.NewInt(requestID), Raw: types.Log{BlockNumber: blockNumber}, } diff --git a/core/services/vrf/v2/listener_v2_types.go b/core/services/vrf/v2/listener_v2_types.go index 4ad645ac17..e8c3a8ccb1 100644 --- a/core/services/vrf/v2/listener_v2_types.go +++ b/core/services/vrf/v2/listener_v2_types.go @@ -41,7 +41,7 @@ func newBatchFulfillment(result vrfPipelineResult, fromAddress common.Address, v }, totalGasLimit: result.gasLimit, runs: []*pipeline.Run{ - &result.run, + result.run, }, reqIDs: []*big.Int{ result.req.req.RequestID(), @@ -95,7 +95,7 @@ func (b *batchFulfillments) addRun(result vrfPipelineResult, fromAddress common. currBatch.proofs = append(currBatch.proofs, result.proof) currBatch.commitments = append(currBatch.commitments, result.reqCommitment) currBatch.totalGasLimit += result.gasLimit - currBatch.runs = append(currBatch.runs, &result.run) + currBatch.runs = append(currBatch.runs, result.run) currBatch.reqIDs = append(currBatch.reqIDs, result.req.req.RequestID()) currBatch.lbs = append(currBatch.lbs, result.req.lb) currBatch.maxFees = append(currBatch.maxFees, result.maxFee) diff --git a/core/services/vrf/v2/listener_v2_types_test.go b/core/services/vrf/v2/listener_v2_types_test.go index 11bb7c9876..5391e18589 100644 --- a/core/services/vrf/v2/listener_v2_types_test.go +++ b/core/services/vrf/v2/listener_v2_types_test.go @@ -10,7 +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/gethwrappers/generated/vrf_coordinator_v2_5" "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" @@ -64,7 +64,7 @@ func Test_BatchFulfillments_AddRun_V2Plus(t *testing.T) { bfs.addRun(vrfPipelineResult{ gasLimit: 500, req: pendingRequest{ - req: NewV2PlusRandomWordsRequested(&vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested{ + req: NewV2_5RandomWordsRequested(&vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested{ RequestId: big.NewInt(1), Raw: types.Log{ TxHash: common.HexToHash("0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65"), @@ -83,7 +83,7 @@ func Test_BatchFulfillments_AddRun_V2Plus(t *testing.T) { bfs.addRun(vrfPipelineResult{ gasLimit: 500, req: pendingRequest{ - req: NewV2PlusRandomWordsRequested(&vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested{ + req: NewV2_5RandomWordsRequested(&vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested{ RequestId: big.NewInt(1), Raw: types.Log{ TxHash: common.HexToHash("0xd8d7ecc4800d25fa53ce0372f13a416d98907a7ef3d8d3bdd79cf4fe75529c65"), diff --git a/core/services/vrf/vrftesthelpers/helpers.go b/core/services/vrf/vrftesthelpers/helpers.go index d40e2bc747..f36fb1ea02 100644 --- a/core/services/vrf/vrftesthelpers/helpers.go +++ b/core/services/vrf/vrftesthelpers/helpers.go @@ -51,6 +51,7 @@ func CreateAndStartBHSJob( app *cltest.TestApplication, bhsAddress, coordinatorV1Address, coordinatorV2Address, coordinatorV2PlusAddress string, trustedBlockhashStoreAddress string, trustedBlockhashStoreBatchSize int32, lookback int, + heartbeatPeriod time.Duration, waitBlocks int, ) job.Job { jid := uuid.New() s := testspecs.GenerateBlockhashStoreSpec(testspecs.BlockhashStoreSpecParams{ @@ -59,8 +60,9 @@ func CreateAndStartBHSJob( CoordinatorV1Address: coordinatorV1Address, CoordinatorV2Address: coordinatorV2Address, CoordinatorV2PlusAddress: coordinatorV2PlusAddress, - WaitBlocks: 100, + WaitBlocks: waitBlocks, LookbackBlocks: lookback, + HeartbeatPeriod: heartbeatPeriod, BlockhashStoreAddress: bhsAddress, TrustedBlockhashStoreAddress: trustedBlockhashStoreAddress, TrustedBlockhashStoreBatchSize: trustedBlockhashStoreBatchSize, diff --git a/core/services/webhook/delegate.go b/core/services/webhook/delegate.go index e373ff8087..ca85a4d162 100644 --- a/core/services/webhook/delegate.go +++ b/core/services/webhook/delegate.go @@ -172,7 +172,7 @@ func (r *webhookJobRunner) RunJob(ctx context.Context, jobUUID uuid.UUID, reques run := pipeline.NewRun(*spec.PipelineSpec, vars) - _, err := r.runner.Run(ctx, &run, jobLggr, true, nil) + _, err := r.runner.Run(ctx, run, jobLggr, true, nil) if err != nil { jobLggr.Errorw("Error running pipeline for webhook job", "err", err) return 0, err diff --git a/core/sessions/orm_test.go b/core/sessions/orm_test.go index 804ea2dbb8..5decb82308 100644 --- a/core/sessions/orm_test.go +++ b/core/sessions/orm_test.go @@ -34,8 +34,8 @@ func TestORM_FindUser(t *testing.T) { t.Parallel() db, orm := setupORM(t) - user1 := cltest.MustNewUser(t, "test1@email1.net", cltest.Password) - user2 := cltest.MustNewUser(t, "test2@email2.net", cltest.Password) + user1 := cltest.MustRandomUser(t) + user2 := cltest.MustRandomUser(t) require.NoError(t, orm.CreateUser(&user1)) require.NoError(t, orm.CreateUser(&user2)) @@ -56,12 +56,11 @@ func TestORM_AuthorizedUserWithSession(t *testing.T) { sessionID string sessionDuration time.Duration wantError string - wantEmail string }{ - {"authorized", "correctID", cltest.MustParseDuration(t, "3m"), "", "have@email"}, - {"expired", "correctID", cltest.MustParseDuration(t, "0m"), sessions.ErrUserSessionExpired.Error(), ""}, - {"incorrect", "wrong", cltest.MustParseDuration(t, "3m"), sessions.ErrUserSessionExpired.Error(), ""}, - {"empty", "", cltest.MustParseDuration(t, "3m"), sessions.ErrEmptySessionID.Error(), ""}, + {"authorized", "correctID", cltest.MustParseDuration(t, "3m"), ""}, + {"expired", "correctID", cltest.MustParseDuration(t, "0m"), sessions.ErrUserSessionExpired.Error()}, + {"incorrect", "wrong", cltest.MustParseDuration(t, "3m"), sessions.ErrUserSessionExpired.Error()}, + {"empty", "", cltest.MustParseDuration(t, "3m"), sessions.ErrEmptySessionID.Error()}, } for _, test := range tests { @@ -69,7 +68,7 @@ func TestORM_AuthorizedUserWithSession(t *testing.T) { db := pgtest.NewSqlxDB(t) orm := sessions.NewORM(db, test.sessionDuration, logger.TestLogger(t), pgtest.NewQConfig(true), &audit.AuditLoggerService{}) - user := cltest.MustNewUser(t, "have@email", cltest.Password) + user := cltest.MustRandomUser(t) require.NoError(t, orm.CreateUser(&user)) prevSession := cltest.NewSession("correctID") @@ -83,7 +82,7 @@ func TestORM_AuthorizedUserWithSession(t *testing.T) { require.EqualError(t, err, test.wantError) } else { require.NoError(t, err) - assert.Equal(t, test.wantEmail, actual.Email) + assert.Equal(t, user.Email, actual.Email) var bumpedSession sessions.Session err = db.Get(&bumpedSession, "SELECT * FROM sessions WHERE ID = $1", prevSession.ID) require.NoError(t, err) @@ -97,13 +96,13 @@ func TestORM_DeleteUser(t *testing.T) { t.Parallel() _, orm := setupORM(t) - _, err := orm.FindUser(cltest.APIEmailAdmin) - require.NoError(t, err) + u := cltest.MustRandomUser(t) + require.NoError(t, orm.CreateUser(&u)) - err = orm.DeleteUser(cltest.APIEmailAdmin) + err := orm.DeleteUser(u.Email) require.NoError(t, err) - _, err = orm.FindUser(cltest.APIEmailAdmin) + _, err = orm.FindUser(u.Email) require.Error(t, err) } @@ -112,14 +111,17 @@ func TestORM_DeleteUserSession(t *testing.T) { db, orm := setupORM(t) + u := cltest.MustRandomUser(t) + require.NoError(t, orm.CreateUser(&u)) + session := sessions.NewSession() - _, err := db.Exec("INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, cltest.APIEmailAdmin) + _, err := db.Exec("INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, u.Email) require.NoError(t, err) err = orm.DeleteUserSession(session.ID) require.NoError(t, err) - _, err = orm.FindUser(cltest.APIEmailAdmin) + _, err = orm.FindUser(u.Email) require.NoError(t, err) sessions, err := orm.Sessions(0, 10) @@ -130,14 +132,17 @@ func TestORM_DeleteUserSession(t *testing.T) { func TestORM_DeleteUserCascade(t *testing.T) { db, orm := setupORM(t) + u := cltest.MustRandomUser(t) + require.NoError(t, orm.CreateUser(&u)) + session := sessions.NewSession() - _, err := db.Exec("INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, cltest.APIEmailAdmin) + _, err := db.Exec("INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, now(), now())", session.ID, u.Email) require.NoError(t, err) - err = orm.DeleteUser(cltest.APIEmailAdmin) + err = orm.DeleteUser(u.Email) require.NoError(t, err) - _, err = orm.FindUser(cltest.APIEmailAdmin) + _, err = orm.FindUser(u.Email) require.Error(t, err) sessions, err := orm.Sessions(0, 10) diff --git a/core/sessions/reaper_test.go b/core/sessions/reaper_test.go index d095a23edd..a96c3822ef 100644 --- a/core/sessions/reaper_test.go +++ b/core/sessions/reaper_test.go @@ -1,7 +1,6 @@ package sessions_test import ( - "database/sql" "testing" "time" @@ -12,7 +11,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/store/models" - "github.com/onsi/gomega" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -36,6 +34,7 @@ func TestSessionReaper_ReapSessions(t *testing.T) { orm := sessions.NewORM(db, config.SessionTimeout().Duration(), lggr, pgtest.NewQConfig(true), audit.NoopLogger) r := sessions.NewSessionReaper(db.DB, config, lggr) + t.Cleanup(func() { assert.NoError(t, r.Stop()) }) @@ -54,34 +53,32 @@ func TestSessionReaper_ReapSessions(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - t.Cleanup(func() { - clearSessions(t, db.DB) - }) + user := cltest.MustRandomUser(t) + require.NoError(t, orm.CreateUser(&user)) - _, err := db.Exec("INSERT INTO sessions (last_used, email, id, created_at) VALUES ($1, $2, $3, now())", test.lastUsed, cltest.APIEmailAdmin, test.name) + session := sessions.NewSession() + session.Email = user.Email + + _, err := db.Exec("INSERT INTO sessions (last_used, email, id, created_at) VALUES ($1, $2, $3, now())", test.lastUsed, user.Email, test.name) require.NoError(t, err) + t.Cleanup(func() { + _, err2 := db.Exec("DELETE FROM sessions where email = $1", user.Email) + require.NoError(t, err2) + }) + r.WakeUp() + <-r.(interface { + WorkDone() <-chan struct{} + }).WorkDone() + sessions, err := orm.Sessions(0, 10) + assert.NoError(t, err) if test.wantReap { - gomega.NewWithT(t).Eventually(func() []sessions.Session { - sessions, err := orm.Sessions(0, 10) - assert.NoError(t, err) - return sessions - }).Should(gomega.HaveLen(0)) + assert.Len(t, sessions, 0) } else { - gomega.NewWithT(t).Consistently(func() []sessions.Session { - sessions, err := orm.Sessions(0, 10) - assert.NoError(t, err) - return sessions - }).Should(gomega.HaveLen(1)) + assert.Len(t, sessions, 1) } }) } } - -// clearSessions removes all sessions. -func clearSessions(t *testing.T, db *sql.DB) { - _, err := db.Exec("DELETE FROM sessions") - require.NoError(t, err) -} diff --git a/core/store/migrate/migrate.go b/core/store/migrate/migrate.go index 97714b68be..69cf9a7824 100644 --- a/core/store/migrate/migrate.go +++ b/core/store/migrate/migrate.go @@ -14,7 +14,9 @@ import ( "github.com/smartcontractkit/sqlx" "gopkg.in/guregu/null.v4" + "github.com/smartcontractkit/chainlink/v2/core/config/env" "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/store/migrate/migrations" // Invoke init() functions within migrations pkg. ) @@ -131,3 +133,14 @@ func Status(db *sql.DB, lggr logger.Logger) error { func Create(db *sql.DB, name, migrationType string) error { return goose.Create(db, "core/store/migrate/migrations", name, migrationType) } + +// SetMigrationENVVars is used to inject values from config to goose migrations via env. +func SetMigrationENVVars(generalConfig chainlink.GeneralConfig) error { + if generalConfig.EVMEnabled() { + err := os.Setenv(env.EVMChainIDNotNullMigration0195, generalConfig.EVMConfigs()[0].ChainID.String()) + if err != nil { + panic(errors.Wrap(err, "failed to set migrations env variables")) + } + } + return nil +} diff --git a/core/store/migrate/migrate_test.go b/core/store/migrate/migrate_test.go index 66764a266f..d6135ce452 100644 --- a/core/store/migrate/migrate_test.go +++ b/core/store/migrate/migrate_test.go @@ -1,6 +1,8 @@ package migrate_test import ( + "math/big" + "os" "testing" "time" @@ -11,13 +13,19 @@ import ( "gopkg.in/guregu/null.v4" "github.com/smartcontractkit/chainlink-relay/pkg/types" + + evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" + "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest/heavyweight" + configtest "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/job" "github.com/smartcontractkit/chainlink/v2/core/services/pipeline" "github.com/smartcontractkit/chainlink/v2/core/services/relay" "github.com/smartcontractkit/chainlink/v2/core/store/migrate" "github.com/smartcontractkit/chainlink/v2/core/store/models" + "github.com/smartcontractkit/chainlink/v2/core/utils" ) var migrationDir = "migrations" @@ -401,3 +409,31 @@ func TestMigrate(t *testing.T) { require.NoError(t, err) require.Equal(t, int64(99), ver) } + +func TestSetMigrationENVVars(t *testing.T) { + t.Run("ValidEVMConfig", func(t *testing.T) { + chainID := utils.NewBig(big.NewInt(1337)) + testConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { + evmEnabled := true + c.EVM = evmcfg.EVMConfigs{&evmcfg.EVMConfig{ + ChainID: chainID, + Enabled: &evmEnabled, + }} + }) + + require.NoError(t, migrate.SetMigrationENVVars(testConfig)) + + actualChainID := os.Getenv(env.EVMChainIDNotNullMigration0195) + require.Equal(t, actualChainID, chainID.String()) + }) + + t.Run("EVMConfigMissing", func(t *testing.T) { + chainID := utils.NewBig(big.NewInt(1337)) + testConfig := configtest.NewGeneralConfig(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.EVM = nil }) + + require.NoError(t, migrate.SetMigrationENVVars(testConfig)) + + actualChainID := os.Getenv(env.EVMChainIDNotNullMigration0195) + require.Equal(t, actualChainID, chainID.String()) + }) +} diff --git a/core/store/migrate/migrations/0195_add_not_null_to_evm_chain_id_in_job_specs.go b/core/store/migrate/migrations/0195_add_not_null_to_evm_chain_id_in_job_specs.go index 4b722c08ba..b1387cc51f 100644 --- a/core/store/migrate/migrations/0195_add_not_null_to_evm_chain_id_in_job_specs.go +++ b/core/store/migrate/migrations/0195_add_not_null_to_evm_chain_id_in_job_specs.go @@ -3,9 +3,12 @@ package migrations import ( "context" "database/sql" + "os" "github.com/pkg/errors" "github.com/pressly/goose/v3" + + "github.com/smartcontractkit/chainlink/v2/core/config/env" ) func init() { @@ -36,6 +39,25 @@ const ( // nolint func Up195(ctx context.Context, tx *sql.Tx) error { + chainID, set := os.LookupEnv(env.EVMChainIDNotNullMigration0195) + if set { + updateQueries := []string{ + `UPDATE direct_request_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, + `UPDATE flux_monitor_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, + `UPDATE ocr_oracle_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, + `UPDATE keeper_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, + `UPDATE vrf_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, + `UPDATE blockhash_store_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, + `UPDATE block_header_feeder_specs SET evm_chain_id = $1 WHERE evm_chain_id IS NULL;`, + } + for i := range updateQueries { + _, err := tx.Exec(updateQueries[i], chainID) + if err != nil { + return errors.Wrap(err, "failed to set missing evm chain ids") + } + } + } + _, err := tx.ExecContext(ctx, addNullConstraintsToSpecs) return errors.Wrap(err, "failed to add null constraints") } diff --git a/core/store/migrate/migrations/0197_add_heartbeat_to_bhs_feeder.sql b/core/store/migrate/migrations/0197_add_heartbeat_to_bhs_feeder.sql new file mode 100644 index 0000000000..74a7a74cd4 --- /dev/null +++ b/core/store/migrate/migrations/0197_add_heartbeat_to_bhs_feeder.sql @@ -0,0 +1,5 @@ +-- +goose Up +ALTER TABLE blockhash_store_specs ADD COLUMN heartbeat_period bigint DEFAULT 0 NOT NULL; + +-- +goose Down +ALTER TABLE blockhash_store_specs DROP COLUMN heartbeat_period; diff --git a/core/store/migrate/migrations/0198_add_block_timestamp_index.sql b/core/store/migrate/migrations/0198_add_block_timestamp_index.sql new file mode 100644 index 0000000000..8f20f4d849 --- /dev/null +++ b/core/store/migrate/migrations/0198_add_block_timestamp_index.sql @@ -0,0 +1,5 @@ +-- +goose Up +create index log_poller_blocks_by_timestamp on evm.log_poller_blocks (evm_chain_id, block_timestamp); + +-- +goose Down +DROP INDEX IF EXISTS evm.log_poller_blocks_by_timestamp; \ No newline at end of file diff --git a/core/store/models/common_test.go b/core/store/models/common_test.go index 1f514142b8..57b7ca73c6 100644 --- a/core/store/models/common_test.go +++ b/core/store/models/common_test.go @@ -203,7 +203,7 @@ func TestDuration_MarshalJSON(t *testing.T) { } for _, test := range tests { t.Run(test.name, func(t *testing.T) { - b, err := json.Marshal(&test.input) + b, err := json.Marshal(test.input) assert.NoError(t, err) assert.Equal(t, test.want, string(b)) }) diff --git a/core/testdata/testspecs/v2_specs.go b/core/testdata/testspecs/v2_specs.go index f2669a6fe9..3dd7c675d5 100644 --- a/core/testdata/testspecs/v2_specs.go +++ b/core/testdata/testspecs/v2_specs.go @@ -606,6 +606,7 @@ type BlockhashStoreSpecParams struct { CoordinatorV2Address string CoordinatorV2PlusAddress string WaitBlocks int + HeartbeatPeriod time.Duration LookbackBlocks int BlockhashStoreAddress string TrustedBlockhashStoreAddress string @@ -704,11 +705,12 @@ pollPeriod = "%s" runTimeout = "%s" evmChainID = "%d" fromAddresses = %s +heartbeatPeriod = "%s" ` toml := fmt.Sprintf(template, params.Name, params.CoordinatorV1Address, params.CoordinatorV2Address, params.CoordinatorV2PlusAddress, params.WaitBlocks, params.LookbackBlocks, params.BlockhashStoreAddress, params.TrustedBlockhashStoreAddress, params.TrustedBlockhashStoreBatchSize, params.PollPeriod.String(), params.RunTimeout.String(), - params.EVMChainID, formattedFromAddresses) + params.EVMChainID, formattedFromAddresses, params.HeartbeatPeriod.String()) return BlockhashStoreSpec{BlockhashStoreSpecParams: params, toml: toml} } diff --git a/core/testdata/tomlspecs/direct-request-spec.toml b/core/testdata/tomlspecs/direct-request-spec.toml deleted file mode 100644 index 35c0cc9274..0000000000 --- a/core/testdata/tomlspecs/direct-request-spec.toml +++ /dev/null @@ -1,13 +0,0 @@ -type = "directrequest" -schemaVersion = 1 -evmChainID = "0" -name = "example eth request event spec" -contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C" -externalJobID = "0EEC7E1D-D0D2-476C-A1A8-72DFB6633F47" -observationSource = """ - ds1 [type=http method=GET url="http://example.com" allowunrestrictednetworkaccess="true"]; - ds1_merge [type=merge left="{}"] - ds1_parse [type=jsonparse path="USD"]; - ds1_multiply [type=multiply times=100]; - ds1 -> ds1_parse -> ds1_multiply; -""" diff --git a/core/utils/big_test.go b/core/utils/big_test.go index ca8be3f90b..e46d46a065 100644 --- a/core/utils/big_test.go +++ b/core/utils/big_test.go @@ -19,7 +19,7 @@ func TestBigFloatMarshal(t *testing.T) { } for _, tc := range tests { - buf, err := json.Marshal(&tc.obj) + buf, err := json.Marshal(tc.obj) require.NoError(t, err) assert.Equal(t, tc.exp, string(buf)) } diff --git a/core/utils/sleeper_task.go b/core/utils/sleeper_task.go index d020799a9c..0b45507a82 100644 --- a/core/utils/sleeper_task.go +++ b/core/utils/sleeper_task.go @@ -19,10 +19,11 @@ type Worker interface { } type sleeperTask struct { - worker Worker - chQueue chan struct{} - chStop chan struct{} - chDone chan struct{} + worker Worker + chQueue chan struct{} + chStop chan struct{} + chDone chan struct{} + chWorkDone chan struct{} StartStopOnce } @@ -36,10 +37,11 @@ type sleeperTask struct { // WakeUp does not block. func NewSleeperTask(worker Worker) SleeperTask { s := &sleeperTask{ - worker: worker, - chQueue: make(chan struct{}, 1), - chStop: make(chan struct{}), - chDone: make(chan struct{}), + worker: worker, + chQueue: make(chan struct{}, 1), + chStop: make(chan struct{}), + chDone: make(chan struct{}), + chWorkDone: make(chan struct{}, 10), } _ = s.StartOnce("SleeperTask-"+worker.Name(), func() error { @@ -83,6 +85,19 @@ func (s *sleeperTask) WakeUp() { } } +func (s *sleeperTask) workDone() { + select { + case s.chWorkDone <- struct{}{}: + default: + } +} + +// WorkDone isn't part of the SleeperTask interface, but can be +// useful in tests to assert that the work has been done. +func (s *sleeperTask) WorkDone() <-chan struct{} { + return s.chWorkDone +} + func (s *sleeperTask) workerLoop() { defer close(s.chDone) @@ -90,6 +105,7 @@ func (s *sleeperTask) workerLoop() { select { case <-s.chQueue: s.worker.Work() + s.workDone() case <-s.chStop: return } diff --git a/core/web/bridge_types_controller_test.go b/core/web/bridge_types_controller_test.go index c875df9453..7184b05f5e 100644 --- a/core/web/bridge_types_controller_test.go +++ b/core/web/bridge_types_controller_test.go @@ -105,7 +105,8 @@ func TestValidateBridgeType(t *testing.T) { for _, test := range tests { t.Run(test.description, func(t *testing.T) { - result := web.ValidateBridgeType(&test.request) + req := test.request + result := web.ValidateBridgeType(&req) assert.Equal(t, test.want, result) }) } diff --git a/core/web/jobs_controller_test.go b/core/web/jobs_controller_test.go index f18fcdd8c2..ca2bd818a8 100644 --- a/core/web/jobs_controller_test.go +++ b/core/web/jobs_controller_test.go @@ -670,7 +670,23 @@ func setupJobSpecsControllerTestsWithJobs(t *testing.T) (*cltest.TestApplication err = app.AddJobV2(testutils.Context(t), &jb) require.NoError(t, err) - erejb, err := directrequest.ValidatedDirectRequestSpec(string(cltest.MustReadFile(t, "../testdata/tomlspecs/direct-request-spec.toml"))) + drSpec := fmt.Sprintf(` + type = "directrequest" + schemaVersion = 1 + evmChainID = "0" + name = "example eth request event spec" + contractAddress = "0x613a38AC1659769640aaE063C651F48E0250454C" + externalJobID = "%s" + observationSource = """ + ds1 [type=http method=GET url="http://example.com" allowunrestrictednetworkaccess="true"]; + ds1_merge [type=merge left="{}"] + ds1_parse [type=jsonparse path="USD"]; + ds1_multiply [type=multiply times=100]; + ds1 -> ds1_parse -> ds1_multiply; + """ + `, uuid.New()) + + erejb, err := directrequest.ValidatedDirectRequestSpec(drSpec) require.NoError(t, err) err = app.AddJobV2(testutils.Context(t), &erejb) require.NoError(t, err) diff --git a/core/web/pipeline_job_spec_errors_controller_test.go b/core/web/pipeline_job_spec_errors_controller_test.go index 13c0237967..8ec77a84f0 100644 --- a/core/web/pipeline_job_spec_errors_controller_test.go +++ b/core/web/pipeline_job_spec_errors_controller_test.go @@ -23,7 +23,7 @@ func TestPipelineJobSpecErrorsController_Delete_2(t *testing.T) { j, err := app.JobORM().FindJob(testutils.Context(t), jID) require.NoError(t, err) t.Log(j.JobSpecErrors) - require.GreaterOrEqual(t, len(j.JobSpecErrors), 1) // second 'got nil head' error may have occured also + require.GreaterOrEqual(t, len(j.JobSpecErrors), 1) // second 'got nil head' error may have occurred also var id int64 = -1 for i := range j.JobSpecErrors { jse := j.JobSpecErrors[i] diff --git a/core/web/presenters/job.go b/core/web/presenters/job.go index 01e01c9fa1..b1f42ebc68 100644 --- a/core/web/presenters/job.go +++ b/core/web/presenters/job.go @@ -330,6 +330,7 @@ type BlockhashStoreSpec struct { CoordinatorV2PlusAddress *ethkey.EIP55Address `json:"coordinatorV2PlusAddress"` WaitBlocks int32 `json:"waitBlocks"` LookbackBlocks int32 `json:"lookbackBlocks"` + HeartbeatPeriod time.Duration `json:"heartbeatPeriod"` BlockhashStoreAddress ethkey.EIP55Address `json:"blockhashStoreAddress"` TrustedBlockhashStoreAddress *ethkey.EIP55Address `json:"trustedBlockhashStoreAddress"` TrustedBlockhashStoreBatchSize int32 `json:"trustedBlockhashStoreBatchSize"` @@ -349,6 +350,7 @@ func NewBlockhashStoreSpec(spec *job.BlockhashStoreSpec) *BlockhashStoreSpec { CoordinatorV2PlusAddress: spec.CoordinatorV2PlusAddress, WaitBlocks: spec.WaitBlocks, LookbackBlocks: spec.LookbackBlocks, + HeartbeatPeriod: spec.HeartbeatPeriod, BlockhashStoreAddress: spec.BlockhashStoreAddress, TrustedBlockhashStoreAddress: spec.TrustedBlockhashStoreAddress, TrustedBlockhashStoreBatchSize: spec.TrustedBlockhashStoreBatchSize, diff --git a/core/web/presenters/job_test.go b/core/web/presenters/job_test.go index a069a3e1ba..bb79c8e953 100644 --- a/core/web/presenters/job_test.go +++ b/core/web/presenters/job_test.go @@ -482,6 +482,7 @@ func TestJob(t *testing.T) { CoordinatorV2PlusAddress: &v2PlusCoordAddress, WaitBlocks: 123, LookbackBlocks: 223, + HeartbeatPeriod: 375 * time.Second, BlockhashStoreAddress: contractAddress, PollPeriod: 25 * time.Second, RunTimeout: 10 * time.Second, @@ -526,6 +527,7 @@ func TestJob(t *testing.T) { "coordinatorV2PlusAddress": "0x92B5e28Ac583812874e4271380c7d070C5FB6E6b", "waitBlocks": 123, "lookbackBlocks": 223, + "heartbeatPeriod": 375000000000, "blockhashStoreAddress": "0x9E40733cC9df84636505f4e6Db28DCa0dC5D1bba", "trustedBlockhashStoreAddress": "0x0ad9FE7a58216242a8475ca92F222b0640E26B63", "trustedBlockhashStoreBatchSize": 20, diff --git a/core/web/resolver/spec.go b/core/web/resolver/spec.go index fa3e5a14fa..48040d118a 100644 --- a/core/web/resolver/spec.go +++ b/core/web/resolver/spec.go @@ -794,6 +794,11 @@ func (b *BlockhashStoreSpecResolver) LookbackBlocks() int32 { return b.spec.LookbackBlocks } +// HeartbeatPeriod returns the job's HeartbeatPeriod param. +func (b *BlockhashStoreSpecResolver) HeartbeatPeriod() string { + return b.spec.HeartbeatPeriod.String() +} + // BlockhashStoreAddress returns the job's BlockhashStoreAddress param. func (b *BlockhashStoreSpecResolver) BlockhashStoreAddress() string { return b.spec.BlockhashStoreAddress.String() diff --git a/core/web/resolver/spec_test.go b/core/web/resolver/spec_test.go index c4efbb6582..04bfffbe05 100644 --- a/core/web/resolver/spec_test.go +++ b/core/web/resolver/spec_test.go @@ -779,6 +779,7 @@ func TestResolver_BlockhashStoreSpec(t *testing.T) { RunTimeout: 37 * time.Second, WaitBlocks: 100, LookbackBlocks: 200, + HeartbeatPeriod: 450 * time.Second, BlockhashStoreAddress: blockhashStoreAddress, TrustedBlockhashStoreAddress: &trustedBlockhashStoreAddress, TrustedBlockhashStoreBatchSize: trustedBlockhashStoreBatchSize, @@ -805,6 +806,7 @@ func TestResolver_BlockhashStoreSpec(t *testing.T) { blockhashStoreAddress trustedBlockhashStoreAddress trustedBlockhashStoreBatchSize + heartbeatPeriod } } } @@ -828,7 +830,8 @@ func TestResolver_BlockhashStoreSpec(t *testing.T) { "lookbackBlocks": 200, "blockhashStoreAddress": "0xb26A6829D454336818477B946f03Fb21c9706f3A", "trustedBlockhashStoreAddress": "0x0ad9FE7a58216242a8475ca92F222b0640E26B63", - "trustedBlockhashStoreBatchSize": 20 + "trustedBlockhashStoreBatchSize": 20, + "heartbeatPeriod": "7m30s" } } } diff --git a/core/web/schema/type/spec.graphql b/core/web/schema/type/spec.graphql index c92a1dd1ea..cdcbabf9ef 100644 --- a/core/web/schema/type/spec.graphql +++ b/core/web/schema/type/spec.graphql @@ -128,6 +128,7 @@ type BlockhashStoreSpec { blockhashStoreAddress: String! trustedBlockhashStoreAddress: String trustedBlockhashStoreBatchSize: Int! + heartbeatPeriod: String! pollPeriod: String! runTimeout: String! evmChainID: String diff --git a/core/web/sessions_controller_test.go b/core/web/sessions_controller_test.go index 41865868b8..7184e3f95b 100644 --- a/core/web/sessions_controller_test.go +++ b/core/web/sessions_controller_test.go @@ -26,6 +26,9 @@ func TestSessionsController_Create(t *testing.T) { app := cltest.NewApplicationEVMDisabled(t) require.NoError(t, app.Start(testutils.Context(t))) + user := cltest.MustRandomUser(t) + require.NoError(t, app.SessionORM().CreateUser(&user)) + client := clhttptest.NewTestLocalOnlyHTTPClient() tests := []struct { name string @@ -33,9 +36,9 @@ func TestSessionsController_Create(t *testing.T) { password string wantSession bool }{ - {"incorrect pwd", cltest.APIEmailAdmin, "incorrect", false}, + {"incorrect pwd", user.Email, "incorrect", false}, {"incorrect email", "incorrect@test.net", cltest.Password, false}, - {"correct", cltest.APIEmailAdmin, cltest.Password, true}, + {"correct", user.Email, cltest.Password, true}, } for _, test := range tests { @@ -76,7 +79,7 @@ func TestSessionsController_Create(t *testing.T) { func mustInsertSession(t *testing.T, q pg.Q, session *sessions.Session) { sql := "INSERT INTO sessions (id, email, last_used, created_at) VALUES ($1, $2, $3, $4) RETURNING *" - _, err := q.Exec(sql, session.ID, cltest.APIEmailAdmin, session.LastUsed, session.CreatedAt) + _, err := q.Exec(sql, session.ID, session.Email, session.LastUsed, session.CreatedAt) require.NoError(t, err) } @@ -86,12 +89,16 @@ func TestSessionsController_Create_ReapSessions(t *testing.T) { app := cltest.NewApplicationEVMDisabled(t) require.NoError(t, app.Start(testutils.Context(t))) + user := cltest.MustRandomUser(t) + require.NoError(t, app.SessionORM().CreateUser(&user)) + staleSession := cltest.NewSession() staleSession.LastUsed = time.Now().Add(-cltest.MustParseDuration(t, "241h")) + staleSession.Email = user.Email q := pg.NewQ(app.GetSqlxDB(), app.GetLogger(), app.GetConfig().Database()) mustInsertSession(t, q, &staleSession) - body := fmt.Sprintf(`{"email":"%s","password":"%s"}`, cltest.APIEmailAdmin, cltest.Password) + body := fmt.Sprintf(`{"email":"%s","password":"%s"}`, user.Email, cltest.Password) resp, err := http.Post(app.Server.URL+"/sessions", "application/json", bytes.NewBufferString(body)) assert.NoError(t, err) defer func() { assert.NoError(t, resp.Body.Close()) }() @@ -116,7 +123,11 @@ func TestSessionsController_Destroy(t *testing.T) { app := cltest.NewApplicationEVMDisabled(t) require.NoError(t, app.Start(testutils.Context(t))) + user := cltest.MustRandomUser(t) + require.NoError(t, app.SessionORM().CreateUser(&user)) + correctSession := sessions.NewSession() + correctSession.Email = user.Email q := pg.NewQ(app.GetSqlxDB(), app.GetLogger(), app.GetConfig().Database()) mustInsertSession(t, q, &correctSession) @@ -158,11 +169,17 @@ func TestSessionsController_Destroy_ReapSessions(t *testing.T) { q := pg.NewQ(app.GetSqlxDB(), app.GetLogger(), app.GetConfig().Database()) require.NoError(t, app.Start(testutils.Context(t))) + user := cltest.MustRandomUser(t) + require.NoError(t, app.SessionORM().CreateUser(&user)) + correctSession := sessions.NewSession() + correctSession.Email = user.Email + mustInsertSession(t, q, &correctSession) cookie := cltest.MustGenerateSessionCookie(t, correctSession.ID) staleSession := cltest.NewSession() + staleSession.Email = user.Email staleSession.LastUsed = time.Now().Add(-cltest.MustParseDuration(t, "241h")) mustInsertSession(t, q, &staleSession) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index b95cc614fb..64bace1993 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,49 +9,50 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [dev] +... + +## 2.6.0 - UNRELEASED + ### Added -- Temporary helper function for proper migration of evmChainID not null in specs, that fills in missing chainIDs. This needs to be removed after one version after everyone migrated properly. For proper migrations all nodes must upgrade sequentially without skipping this version. +- Simple password use in production builds is now disallowed - nodes with this configuration will not boot and will not pass config validation. +- Helper migrations function for injecting env vars into goose migrations. This was done to inject chainID into evm chain id not null in specs migrations. +- OCR2 jobs now support querying the state contract for configurations if it has been deployed. This can help on chains such as BSC which "manage" state bloat by arbitrarily deleting logs older than a certain date. In this case, if logs are missing we will query the contract directly and retrieve the latest config from chain state. Chainlink will perform no extra RPC calls unless the job spec has this feature explicitly enabled. On chains that require this, nops may see an increase in RPC calls. This can be enabled for OCR2 jobs by specifying `ConfigContractAddress` in the relay config TOML. ### Removed -- Removed support for sending telemetry to the deprecated Explorer service. All nodes will have to remove `Explorer` related keys from TOML configuration and env vars. +- Removed support for sending telemetry to the deprecated Explorer service. All nodes will have to remove `Explorer` related keys from TOML configuration and env vars. - Removed default evmChainID logic where evmChainID was implicitly injected into the jobspecs based on node EVM chainID toml configuration. All newly created jobs(that have evmChainID field) will have to explicitly define evmChainID in the jobspec. - Removed keyset migration that migrated v1 keys to v2 keys. All keys should've been migrated by now, and we don't permit creation of new v1 keys anymore - All nodes will have to remove the following secret configurations: - * `Explorer.AccessKey` - * `Explorer.Secret` - - All nodes will have to remove the following configuration field: `ExplorerURL` +All nodes will have to remove the following secret configurations: + +- `Explorer.AccessKey` +- `Explorer.Secret` + +All nodes will have to remove the following configuration field: `ExplorerURL` ### Fixed + - Unauthenticated users executing CLI commands previously generated a confusing error log, which is now removed: -```[ERROR] Error in transaction, rolling back: session missing or expired, please login again pg/transaction.go:118 ``` + `[ERROR] Error in transaction, rolling back: session missing or expired, please login again pg/transaction.go:118 ` - Fixed a bug that was preventing job runs to be displayed when the job `chainID` was disabled. - `chainlink txs evm create` returns a transaction hash for the attempted transaction in the CLI. Previously only the sender, recipient and `unstarted` state were returned. - Fixed a bug where `evmChainId` is requested instead of `id` or `evm-chain-id` in CLI error verbatim - Fixed a bug that would cause the node to shut down while performing backup -- Fixed health checker to include more services in the prometheus `health` metric and HTTP `/health` endpoint +- Fixed health checker to include more services in the prometheus `health` metric and HTTP `/health` endpoint +- Fixed a bug where prices would not be parsed correctly in telemetry data -## 2.5.0 - UNRELEASED -======= + -- Unauthenticated users executing CLI commands previously generated a confusing error log, which is now removed: - ``` - [ERROR] Error in transaction, rolling back: session missing or expired, please login again pg/transaction.go:118 - ``` -- Fixed a bug that was preventing job runs to be displayed when the job `chainID` was disabled. -- `chainlink txs evm create` returns a transaction hash for the attempted transaction in the CLI. Previously only the sender, receipient and `unstarted` state were returned. +## 2.5.0 - 2023-09-13 ### Added - New prometheus metrics for mercury: - - `mercury_price_feed_missing` - - `mercury_price_feed_errors` - Nops may wish to add alerting on these. - - + - `mercury_price_feed_missing` + - `mercury_price_feed_errors` + Nops may wish to add alerting on these. ### Upcoming Required Configuration Change diff --git a/docs/CHANGELOG_CCIP.md b/docs/CHANGELOG_CCIP.md index 6d8b37b140..3ead90b347 100644 --- a/docs/CHANGELOG_CCIP.md +++ b/docs/CHANGELOG_CCIP.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### Changed +- PriceUpdate now accepts an array of gas price update + - Removed `destChainSelector` and `usdPerUnitGas` from PriceUpdates + - Added `GasPriceUpdate[] gasPriceUpdates` to PriceUpdates. Each `GasPriceUpdate` struct contains `destChainSelector` and `usdPerUnitGas`. - OnRamp fee calculation logic now includes L1 security fee if sending to L2. - New field `destBytesOverhead` added to **TokenTransferFeeConfig**. - `destBytesOverhead` is the size of additional bytes being passed to destination for token transfers. For example, USDC transfers require additional attestation data. @@ -20,6 +23,21 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `destDataAvailabilityOverheadGas` is the extra data availability gas charged on top of message data. - `destGasPerDataAvailabilityByte` is the amount of gas to charge per byte of data that needs data availability. - `destDataAvailabilityMultiplier` is the multiplier for data availability gas. It is in multiples of 1e-4, or 0.0001. It can represent calldata compression factor on Optimistic Rollups. +- OnRamp token transfer fee calculation updated. + - `minTokenTransferFeeUSD` and `maxTokenTransferFeeUSD` are removed from FeeTokenConfig. + - `minFeeUSD` and `maxFeeUSD` are added to TokenTransferFeeConfig, they will be applied at a per-token level. + - token transfer premium is calculated as the sum of each individual token transfer fee. +- MessageId hashing logic updated. + - the new `sourceTokenData` field is added to the hash. + - fixed-size fields are hashed in nested hash function. +- CommitStore OffchainConfig fields updated. + - New fields `GasPriceHeartBeat`, `DAGasPriceDeviationPPB`, `ExecGasPriceDeviationPPB`, `TokenPriceHeartBeat`, `TokenPriceDeviationPPB` added + - `GasPriceHeartBeat` specifies an update heartbeat threshold for gas prices + - `DAGasPriceDeviationPPB` specifies deviation PPB threshold for dava availability (DA) gas price. On chains without DA component, this should be 0. + - `ExecGasPriceDeviationPPB` specifies deviation PPB threshold for native EVM execution gas price. + - `TokenPriceHeartBeat` specifies an update heartbeat threshold for token prices + - `TokenPriceDeviationPPB` specifies deviation PPB threshold for token price. + - Old Fields `FeeUpdateHeartBeat`, `FeeUpdateDeviationPPB` removed. They are replaced by the fields above. ### Removed diff --git a/go.mod b/go.mod index 62b95d276d..6148f69ddd 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/smartcontractkit/chainlink/v2 -go 1.20 +go 1.21 require ( github.com/CosmWasm/wasmd v0.40.1 @@ -53,7 +53,7 @@ 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.9 + github.com/pelletier/go-toml/v2 v2.1.0 github.com/pkg/errors v0.9.1 github.com/pressly/goose/v3 v3.15.0 github.com/prometheus/client_golang v1.16.0 @@ -69,12 +69,12 @@ require ( github.com/smartcontractkit/caigo v0.0.0-20230621050857-b29a4ca8c704 github.com/smartcontractkit/chain-selectors v1.0.2 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47 - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230918212835-8a0b08df72a3 + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230926113942-a871b2976dc1 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230828183543-6d0939746966 - github.com/smartcontractkit/libocr v0.0.0-20230918212407-dbd4e505b3e6 - github.com/smartcontractkit/ocr2keepers v0.7.24 + github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6 + github.com/smartcontractkit/ocr2keepers v0.7.27 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-20230906073235-9e478e5e19f1 diff --git a/go.sum b/go.sum index d5d83a332f..ac7ed3e5d1 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,7 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP 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.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk= +cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= 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= @@ -26,11 +27,14 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/compute v1.22.0 h1:cB8R6FtUtT1TYGl5R3xuxnW6OUIc/DrT2aiR16TTG7Y= +cloud.google.com/go/compute v1.22.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= 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/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= 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= @@ -42,6 +46,7 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX 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.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM= +cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= 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= @@ -55,9 +60,11 @@ cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3s 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/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= 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= +cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= 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= @@ -104,17 +111,22 @@ github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYr 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.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/OneOfOne/xxhash v1.2.5/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= 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/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= 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/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= +github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= 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= @@ -123,10 +135,12 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAu 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/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= 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/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4= +github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= 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= @@ -134,11 +148,13 @@ github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJ 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-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/avast/retry-go/v4 v4.5.0 h1:QoRAZZ90cj5oni2Lsgl2GW8mNTnUCnmpx/iKpwVisHg= github.com/avast/retry-go/v4 v4.5.0/go.mod h1:7hLEXp0oku2Nir2xBAsg0PTphp9z71bN5Aq1fboC3+I= 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.44.302 h1:ST3ko6GrJKn3Xi+nAvxjG3uk/V1pW8KC52WLeIxqqNk= +github.com/aws/aws-sdk-go v1.44.302/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= @@ -154,6 +170,7 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce 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/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= 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= @@ -165,6 +182,7 @@ github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/i github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= +github.com/btcsuite/btcd/btcutil v1.1.2/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= @@ -175,8 +193,10 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40Nwln+M/+faA= +github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= 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= @@ -185,8 +205,10 @@ github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.7.5/go.mod h1:R/pdNYDYFQk+tuuOo7 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/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -203,6 +225,7 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583j github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 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/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 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= @@ -212,10 +235,13 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 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/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= +github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= 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= @@ -229,6 +255,7 @@ github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5w github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= 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/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= 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.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= @@ -236,6 +263,7 @@ github.com/cometbft/cometbft-db v0.8.0/go.mod h1:6ASCP4pfhmrCBpfk01/9E1SI29nD3Hf 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.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU= +github.com/containerd/continuity v0.4.1/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= 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= @@ -257,6 +285,7 @@ github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXy github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= 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= @@ -268,16 +297,21 @@ github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980 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/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= 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/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= 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.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= 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= @@ -293,10 +327,12 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6Uh github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= 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/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= +github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= 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= @@ -319,6 +355,7 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8 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/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= @@ -339,6 +376,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= @@ -361,12 +399,16 @@ 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.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/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= 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/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 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= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= @@ -437,6 +479,7 @@ github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= 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= @@ -450,6 +493,7 @@ github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogB github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= 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/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= 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= @@ -463,11 +507,13 @@ github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPr github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= 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-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= 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= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= 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= @@ -510,6 +556,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt 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.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= @@ -577,6 +624,7 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi 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/orderedcode v0.0.1 h1:UzfcAexk9Vhv8+9pNOgRu41f16lHq725vPwnSeiG/Us= +github.com/google/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= 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= @@ -592,6 +640,7 @@ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/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/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= 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= @@ -600,15 +649,19 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= +github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= 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/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= 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= @@ -655,10 +708,13 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv 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-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= 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-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-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= 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= @@ -672,13 +728,16 @@ github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9 github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= +github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 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.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 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-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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= @@ -720,6 +779,7 @@ 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/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -836,13 +896,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/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= 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/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.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= +github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -865,6 +928,7 @@ 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/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= @@ -1135,6 +1199,7 @@ github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN 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/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -1165,6 +1230,7 @@ github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWV 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 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= +github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 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= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -1182,6 +1248,7 @@ github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjK 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/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= 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= @@ -1208,6 +1275,7 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh 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/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= 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= @@ -1298,6 +1366,7 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= +github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -1317,6 +1386,7 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1330,12 +1400,15 @@ github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJK 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.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/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.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= 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= @@ -1345,8 +1418,8 @@ 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.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= -github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/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= @@ -1396,12 +1469,15 @@ github.com/prometheus/prometheus v0.46.0 h1:9JSdXnsuT6YsbODEhSQMwxNkGwPExfmzqG73 github.com/prometheus/prometheus v0.46.0/go.mod h1:10L5IJE5CEsjee1FnOcVswYXlPIscDWWt3IJ2UDYrz4= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= +github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= 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/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= 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-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/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= @@ -1417,6 +1493,7 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= @@ -1440,6 +1517,7 @@ github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCM github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 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/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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= github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= @@ -1464,8 +1542,8 @@ github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc4 github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47/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.20230918212835-8a0b08df72a3 h1:FonaZ1kgRK0yY7D0jF5pL3K+0DYUnKcnStOOcIN+Hhg= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230918212835-8a0b08df72a3/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230926113942-a871b2976dc1 h1:Db333w+fSm2e18LMikcIQHIZqgxZruW9uCUGJLUC9mI= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230926113942-a871b2976dc1/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= @@ -1478,10 +1556,10 @@ github.com/smartcontractkit/go-plugin v0.0.0-20230605132010-0f4d515d1472 h1:x3kN 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-20230918212407-dbd4e505b3e6 h1:w+8TI2Vcm3vk8XQz40ddcwy9BNZgoakXIby35Y54iDU= -github.com/smartcontractkit/libocr v0.0.0-20230918212407-dbd4e505b3e6/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.24 h1:d1HcCpsBcBSC9MC9qdjzsm/NSAnnavcZAvAqPAAa75Q= -github.com/smartcontractkit/ocr2keepers v0.7.24/go.mod h1:4e1ZDRz7fpLgcRUjJpq+5mkoD0ga11BxrSp2JTWKADQ= +github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6 h1:eSo9r53fARv2MnIO5pqYvQOXMBsTlAwhHyQ6BAVp6bY= +github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.7.27 h1:kwqMrzmEdq6gH4yqNuLQCbdlED0KaIjwZzu3FF+Gves= +github.com/smartcontractkit/ocr2keepers v0.7.27/go.mod h1:1QGzJURnoWpysguPowOe2bshV0hNp1YX10HHlhDEsas= 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= @@ -1592,6 +1670,7 @@ github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95 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/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -1603,6 +1682,7 @@ github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQ 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/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= 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= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -1630,6 +1710,7 @@ 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/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= 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= @@ -1693,6 +1774,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= @@ -2085,6 +2167,7 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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-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.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM= @@ -2110,6 +2193,7 @@ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ 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.132.0 h1:8t2/+qZ26kAOGSmOiHwVycqVaDg7q3JDILrNi/Z6rvc= +google.golang.org/api v0.132.0/go.mod h1:AeTBC6GpJnJSRJjktDcPX0QwtS8pGYZOV6MSuSCusw0= 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= @@ -2267,6 +2351,7 @@ 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.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= 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= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2296,16 +2381,27 @@ k8s.io/kubectl v0.25.11/go.mod h1:8mIfgkFgT+yJ8/TlmPW1qoRh46H2si9q5nW8id7i9iM= k8s.io/utils v0.0.0-20230711102312-30195339c3c7 h1:ZgnF1KZsYxWIifwSNZFZgNtWE89WI5yiP5WwlfDoIyc= k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= +lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= modernc.org/ccgo/v3 v3.16.14 h1:af6KNtFgsVmnDYrWk3PQCS9XT6BXe7o3ZFJKkIKvXNQ= +modernc.org/ccgo/v3 v3.16.14/go.mod h1:mPDSujUIaTNWQSG4eqKw+atqLOEbma6Ncsa94WbC9zo= modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM= +modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o= +modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= +modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA= +modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= +modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= 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= diff --git a/integration-tests/.tool-versions b/integration-tests/.tool-versions index 563ef48e9a..68b6d99419 100644 --- a/integration-tests/.tool-versions +++ b/integration-tests/.tool-versions @@ -1,4 +1,4 @@ -golang 1.21.0 +golang 1.21.1 k3d 5.4.6 kubectl 1.25.5 nodejs 18.13.0 diff --git a/integration-tests/actions/ocr2_helpers.go b/integration-tests/actions/ocr2_helpers.go index 293ea2b73c..aead74f2bd 100644 --- a/integration-tests/actions/ocr2_helpers.go +++ b/integration-tests/actions/ocr2_helpers.go @@ -35,12 +35,13 @@ func DeployOCRv2Contracts( contractDeployer contracts.ContractDeployer, transmitters []string, client blockchain.EVMClient, + ocrOptions contracts.OffchainOptions, ) ([]contracts.OffchainAggregatorV2, error) { var ocrInstances []contracts.OffchainAggregatorV2 for contractCount := 0; contractCount < numberOfContracts; contractCount++ { ocrInstance, err := contractDeployer.DeployOffchainAggregatorV2( linkTokenContract.Address(), - contracts.DefaultOffChainAggregatorOptions(), + ocrOptions, ) if err != nil { return nil, fmt.Errorf("OCRv2 instance deployment have failed: %w", err) diff --git a/integration-tests/actions/ocr2_helpers_local.go b/integration-tests/actions/ocr2_helpers_local.go index c1e863561d..0b20e4cfee 100644 --- a/integration-tests/actions/ocr2_helpers_local.go +++ b/integration-tests/actions/ocr2_helpers_local.go @@ -4,6 +4,9 @@ import ( "crypto/ed25519" "encoding/hex" "fmt" + "strings" + "time" + "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" "github.com/lib/pq" @@ -13,14 +16,13 @@ import ( "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/services/ocr2/testhelpers" "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( @@ -128,12 +130,12 @@ func CreateOCRv2JobsLocal( return nil } -func BuildMedianOCR2ConfigLocal(workerNodes []*client.ChainlinkClient) (*contracts.OCRv2Config, error) { +func BuildMedianOCR2ConfigLocal(workerNodes []*client.ChainlinkClient, ocrOffchainOptions contracts.OffchainOptions) (*contracts.OCRv2Config, error) { S, oracleIdentities, err := GetOracleIdentitiesWithKeyIndexLocal(workerNodes, 0) if err != nil { return nil, err } - signerKeys, transmitterAccounts, f_, onchainConfig, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTests( + signerKeys, transmitterAccounts, f_, _, offchainConfigVersion, offchainConfig, err := confighelper.ContractSetConfigArgsForTests( 30*time.Second, // deltaProgress time.Duration, 30*time.Second, // deltaResend time.Duration, 10*time.Second, // deltaRound time.Duration, @@ -173,6 +175,8 @@ func BuildMedianOCR2ConfigLocal(workerNodes []*client.ChainlinkClient) (*contrac transmitterAddresses = append(transmitterAddresses, common.HexToAddress(string(account))) } + onchainConfig, err := testhelpers.GenerateDefaultOCR2OnchainConfig(ocrOffchainOptions.MinimumAnswer, ocrOffchainOptions.MaximumAnswer) + return &contracts.OCRv2Config{ Signers: signerAddresses, Transmitters: transmitterAddresses, @@ -180,7 +184,7 @@ func BuildMedianOCR2ConfigLocal(workerNodes []*client.ChainlinkClient) (*contrac OnchainConfig: onchainConfig, OffchainConfigVersion: offchainConfigVersion, OffchainConfig: []byte(fmt.Sprintf("0x%s", offchainConfig)), - }, nil + }, err } func GetOracleIdentitiesWithKeyIndexLocal( diff --git a/integration-tests/actions/vrfv2plus/vrfv2plus_constants/constants.go b/integration-tests/actions/vrfv2plus/vrfv2plus_constants/constants.go index 1ecb3a2418..bb266e7c2c 100644 --- a/integration-tests/actions/vrfv2plus/vrfv2plus_constants/constants.go +++ b/integration-tests/actions/vrfv2plus/vrfv2plus_constants/constants.go @@ -1,31 +1,40 @@ package vrfv2plus_constants import ( - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" "math/big" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" ) var ( - LinkEthFeedResponse = big.NewInt(1e18) + LinkNativeFeedResponse = big.NewInt(1e18) MinimumConfirmations = uint16(3) RandomnessRequestCountPerRequest = uint16(1) - VRFSubscriptionFundingAmountLink = big.NewInt(100) + VRFSubscriptionFundingAmountLink = big.NewInt(10) VRFSubscriptionFundingAmountNativeToken = big.NewInt(1) - ChainlinkNodeFundingAmountEth = big.NewFloat(0.1) + ChainlinkNodeFundingAmountNative = big.NewFloat(0.1) NumberOfWords = uint32(3) CallbackGasLimit = uint32(1000000) MaxGasLimitVRFCoordinatorConfig = uint32(2.5e6) StalenessSeconds = uint32(86400) GasAfterPaymentCalculation = uint32(33825) - VRFCoordinatorV2PlusFeeConfig = vrf_coordinator_v2plus.VRFCoordinatorV2PlusFeeConfig{ - FulfillmentFlatFeeLinkPPM: 500, - FulfillmentFlatFeeEthPPM: 500, + VRFCoordinatorV2_5FeeConfig = vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig{ + FulfillmentFlatFeeLinkPPM: 500, + FulfillmentFlatFeeNativePPM: 500, } VRFCoordinatorV2PlusUpgradedVersionFeeConfig = vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionFeeConfig{ - FulfillmentFlatFeeLinkPPM: 500, - FulfillmentFlatFeeEthPPM: 500, + FulfillmentFlatFeeLinkPPM: 500, + FulfillmentFlatFeeNativePPM: 500, } + + WrapperGasOverhead = uint32(50_000) + CoordinatorGasOverhead = uint32(52_000) + WrapperPremiumPercentage = uint8(25) + WrapperMaxNumberOfWords = uint8(10) + WrapperConsumerFundingAmountNativeToken = big.NewFloat(1) + + WrapperConsumerFundingAmountLink = big.NewInt(10) ) diff --git a/integration-tests/actions/vrfv2plus/vrfv2plus_models.go b/integration-tests/actions/vrfv2plus/vrfv2plus_models.go index eb98393c27..c227d490eb 100644 --- a/integration-tests/actions/vrfv2plus/vrfv2plus_models.go +++ b/integration-tests/actions/vrfv2plus/vrfv2plus_models.go @@ -23,8 +23,13 @@ type VRFV2PlusData struct { ChainID *big.Int } -type VRFV2PlusContracts struct { - Coordinator contracts.VRFCoordinatorV2Plus +type VRFV2_5Contracts struct { + Coordinator contracts.VRFCoordinatorV2_5 BHS contracts.BlockHashStore LoadTestConsumers []contracts.VRFv2PlusLoadTestConsumer } + +type VRFV2PlusWrapperContracts struct { + VRFV2PlusWrapper contracts.VRFV2PlusWrapper + LoadTestConsumers []contracts.VRFv2PlusWrapperLoadTestConsumer +} diff --git a/integration-tests/actions/vrfv2plus/vrfv2plus_steps.go b/integration-tests/actions/vrfv2plus/vrfv2plus_steps.go index 3ee226eba7..aa6dba8e1b 100644 --- a/integration-tests/actions/vrfv2plus/vrfv2plus_steps.go +++ b/integration-tests/actions/vrfv2plus/vrfv2plus_steps.go @@ -3,6 +3,9 @@ package vrfv2plus import ( "context" "fmt" + "math/big" + "time" + "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" "github.com/pkg/errors" @@ -14,51 +17,54 @@ import ( "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" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" + "github.com/smartcontractkit/chainlink/v2/core/assets" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/utils" - "math/big" - "time" ) var ( - ErrNodePrimaryKey = "error getting node's primary ETH key" - ErrCreatingProvingKeyHash = "error creating a keyHash from the proving key" - ErrRegisteringProvingKey = "error registering a proving key on Coordinator contract" - ErrRegisterProvingKey = "error registering proving keys" - ErrEncodingProvingKey = "error encoding proving key" - ErrCreatingVRFv2PlusKey = "error creating VRFv2Plus key" - ErrDeployBlockHashStore = "error deploying blockhash store" - ErrDeployCoordinator = "error deploying VRF CoordinatorV2Plus" - ErrAdvancedConsumer = "error deploying VRFv2Plus Advanced Consumer" - ErrABIEncodingFunding = "error Abi encoding subscriptionID" - ErrSendingLinkToken = "error sending Link token" - ErrCreatingVRFv2PlusJob = "error creating VRFv2Plus job" - ErrParseJob = "error parsing job definition" - ErrDeployVRFV2PlusContracts = "error deploying VRFV2Plus contracts" - ErrSetVRFCoordinatorConfig = "error setting config for VRF Coordinator contract" - ErrCreateVRFSubscription = "error creating VRF Subscription" - ErrFindSubID = "error finding created subscription ID" - ErrAddConsumerToSub = "error adding consumer to VRF Subscription" - ErrFundSubWithNativeToken = "error funding subscription with native token" - ErrSetLinkETHLinkFeed = "error setting Link and ETH/LINK feed for VRF Coordinator contract" - ErrFundSubWithLinkToken = "error funding subscription with Link tokens" - ErrCreateVRFV2PlusJobs = "error creating VRF V2 Plus Jobs" - ErrGetPrimaryKey = "error getting primary ETH key address" - ErrRestartCLNode = "error restarting CL node" - ErrWaitTXsComplete = "error waiting for TXs to complete" - ErrRequestRandomness = "error requesting randomness" + ErrNodePrimaryKey = "error getting node's primary ETH key" + ErrCreatingProvingKeyHash = "error creating a keyHash from the proving key" + ErrRegisteringProvingKey = "error registering a proving key on Coordinator contract" + ErrRegisterProvingKey = "error registering proving keys" + ErrEncodingProvingKey = "error encoding proving key" + ErrCreatingVRFv2PlusKey = "error creating VRFv2Plus key" + ErrDeployBlockHashStore = "error deploying blockhash store" + ErrDeployCoordinator = "error deploying VRF CoordinatorV2Plus" + ErrAdvancedConsumer = "error deploying VRFv2Plus Advanced Consumer" + ErrABIEncodingFunding = "error Abi encoding subscriptionID" + ErrSendingLinkToken = "error sending Link token" + ErrCreatingVRFv2PlusJob = "error creating VRFv2Plus job" + ErrParseJob = "error parsing job definition" + ErrDeployVRFV2_5Contracts = "error deploying VRFV2_5 contracts" + ErrSetVRFCoordinatorConfig = "error setting config for VRF Coordinator contract" + ErrCreateVRFSubscription = "error creating VRF Subscription" + ErrFindSubID = "error finding created subscription ID" + ErrAddConsumerToSub = "error adding consumer to VRF Subscription" + ErrFundSubWithNativeToken = "error funding subscription with native token" + ErrSetLinkNativeLinkFeed = "error setting Link and ETH/LINK feed for VRF Coordinator contract" + ErrFundSubWithLinkToken = "error funding subscription with Link tokens" + ErrCreateVRFV2PlusJobs = "error creating VRF V2 Plus Jobs" + ErrGetPrimaryKey = "error getting primary ETH key address" + ErrRestartCLNode = "error restarting CL node" + ErrWaitTXsComplete = "error waiting for TXs to complete" + ErrRequestRandomness = "error requesting randomness" + ErrRequestRandomnessDirectFundingLinkPayment = "error requesting randomness with direct funding and link payment" + ErrRequestRandomnessDirectFundingNativePayment = "error requesting randomness with direct funding and native payment" + ErrWaitRandomWordsRequestedEvent = "error waiting for RandomWordsRequested event" ErrWaitRandomWordsFulfilledEvent = "error waiting for RandomWordsFulfilled event" ErrLinkTotalBalance = "error waiting for RandomWordsFulfilled event" ErrNativeTokenBalance = "error waiting for RandomWordsFulfilled event" + ErrDeployWrapper = "error deploying VRFV2PlusWrapper" ) -func DeployVRFV2PlusContracts( +func DeployVRFV2_5Contracts( contractDeployer contracts.ContractDeployer, chainClient blockchain.EVMClient, consumerContractsAmount int, -) (*VRFV2PlusContracts, error) { +) (*VRFV2_5Contracts, error) { bhs, err := contractDeployer.DeployBlockhashStore() if err != nil { return nil, errors.Wrap(err, ErrDeployBlockHashStore) @@ -67,7 +73,7 @@ func DeployVRFV2PlusContracts( if err != nil { return nil, errors.Wrap(err, ErrWaitTXsComplete) } - coordinator, err := contractDeployer.DeployVRFCoordinatorV2Plus(bhs.Address()) + coordinator, err := contractDeployer.DeployVRFCoordinatorV2_5(bhs.Address()) if err != nil { return nil, errors.Wrap(err, ErrDeployCoordinator) } @@ -75,7 +81,7 @@ func DeployVRFV2PlusContracts( if err != nil { return nil, errors.Wrap(err, ErrWaitTXsComplete) } - consumers, err := DeployConsumers(contractDeployer, coordinator, consumerContractsAmount) + consumers, err := DeployVRFV2PlusConsumers(contractDeployer, coordinator, consumerContractsAmount) if err != nil { return nil, err } @@ -83,10 +89,39 @@ func DeployVRFV2PlusContracts( if err != nil { return nil, errors.Wrap(err, ErrWaitTXsComplete) } - return &VRFV2PlusContracts{coordinator, bhs, consumers}, nil + return &VRFV2_5Contracts{coordinator, bhs, consumers}, nil } -func DeployConsumers(contractDeployer contracts.ContractDeployer, coordinator contracts.VRFCoordinatorV2Plus, consumerContractsAmount int) ([]contracts.VRFv2PlusLoadTestConsumer, error) { +func DeployVRFV2PlusDirectFundingContracts( + contractDeployer contracts.ContractDeployer, + chainClient blockchain.EVMClient, + linkTokenAddress string, + linkEthFeedAddress string, + coordinator contracts.VRFCoordinatorV2_5, + consumerContractsAmount int, +) (*VRFV2PlusWrapperContracts, error) { + + vrfv2PlusWrapper, err := contractDeployer.DeployVRFV2PlusWrapper(linkTokenAddress, linkEthFeedAddress, coordinator.Address()) + if err != nil { + return nil, errors.Wrap(err, ErrDeployWrapper) + } + err = chainClient.WaitForEvents() + if err != nil { + return nil, errors.Wrap(err, ErrWaitTXsComplete) + } + + consumers, err := DeployVRFV2PlusWrapperConsumers(contractDeployer, linkTokenAddress, vrfv2PlusWrapper, consumerContractsAmount) + if err != nil { + return nil, err + } + err = chainClient.WaitForEvents() + if err != nil { + return nil, errors.Wrap(err, ErrWaitTXsComplete) + } + return &VRFV2PlusWrapperContracts{vrfv2PlusWrapper, consumers}, nil +} + +func DeployVRFV2PlusConsumers(contractDeployer contracts.ContractDeployer, coordinator contracts.VRFCoordinatorV2_5, consumerContractsAmount int) ([]contracts.VRFv2PlusLoadTestConsumer, error) { var consumers []contracts.VRFv2PlusLoadTestConsumer for i := 1; i <= consumerContractsAmount; i++ { loadTestConsumer, err := contractDeployer.DeployVRFv2PlusLoadTestConsumer(coordinator.Address()) @@ -98,6 +133,18 @@ func DeployConsumers(contractDeployer contracts.ContractDeployer, coordinator co return consumers, nil } +func DeployVRFV2PlusWrapperConsumers(contractDeployer contracts.ContractDeployer, linkTokenAddress string, vrfV2PlusWrapper contracts.VRFV2PlusWrapper, consumerContractsAmount int) ([]contracts.VRFv2PlusWrapperLoadTestConsumer, error) { + var consumers []contracts.VRFv2PlusWrapperLoadTestConsumer + for i := 1; i <= consumerContractsAmount; i++ { + loadTestConsumer, err := contractDeployer.DeployVRFV2PlusWrapperLoadTestConsumer(linkTokenAddress, vrfV2PlusWrapper.Address()) + if err != nil { + return nil, errors.Wrap(err, ErrAdvancedConsumer) + } + consumers = append(consumers, loadTestConsumer) + } + return consumers, nil +} + func CreateVRFV2PlusJob( chainlinkNode *client.ChainlinkClient, coordinatorAddress string, @@ -133,10 +180,10 @@ func CreateVRFV2PlusJob( return job, nil } -func VRFV2PlusRegisterProvingKey( +func VRFV2_5RegisterProvingKey( vrfKey *client.VRFKey, oracleAddress string, - coordinator contracts.VRFCoordinatorV2Plus, + coordinator contracts.VRFCoordinatorV2_5, ) (VRFV2PlusEncodedProvingKey, error) { provingKey, err := actions.EncodeOnChainVRFProvingKey(*vrfKey) if err != nil { @@ -171,7 +218,7 @@ func VRFV2PlusUpgradedVersionRegisterProvingKey( return provingKey, nil } -func FundVRFCoordinatorV2PlusSubscription(linkToken contracts.LinkToken, coordinator contracts.VRFCoordinatorV2Plus, chainClient blockchain.EVMClient, subscriptionID *big.Int, linkFundingAmount *big.Int) error { +func FundVRFCoordinatorV2_5Subscription(linkToken contracts.LinkToken, coordinator contracts.VRFCoordinatorV2_5, chainClient blockchain.EVMClient, subscriptionID *big.Int, linkFundingAmount *big.Int) error { encodedSubId, err := chainlinkutils.ABIEncode(`[{"type":"uint256"}]`, subscriptionID) if err != nil { return errors.Wrap(err, ErrABIEncodingFunding) @@ -183,31 +230,31 @@ func FundVRFCoordinatorV2PlusSubscription(linkToken contracts.LinkToken, coordin return chainClient.WaitForEvents() } -func SetupVRFV2PlusEnvironment( +func SetupVRFV2_5Environment( env *test_env.CLClusterTestEnv, - linkAddress contracts.LinkToken, - mockETHLinkFeedAddress contracts.MockETHLINKFeed, + linkToken contracts.LinkToken, + mockNativeLINKFeed contracts.MockETHLINKFeed, consumerContractsAmount int, -) (*VRFV2PlusContracts, *big.Int, *VRFV2PlusData, error) { +) (*VRFV2_5Contracts, *big.Int, *VRFV2PlusData, error) { - vrfv2PlusContracts, err := DeployVRFV2PlusContracts(env.ContractDeployer, env.EVMClient, consumerContractsAmount) + vrfv2_5Contracts, err := DeployVRFV2_5Contracts(env.ContractDeployer, env.EVMClient, consumerContractsAmount) if err != nil { - return nil, nil, nil, errors.Wrap(err, ErrDeployVRFV2PlusContracts) + return nil, nil, nil, errors.Wrap(err, ErrDeployVRFV2_5Contracts) } - err = vrfv2PlusContracts.Coordinator.SetConfig( + err = vrfv2_5Contracts.Coordinator.SetConfig( vrfv2plus_constants.MinimumConfirmations, vrfv2plus_constants.MaxGasLimitVRFCoordinatorConfig, vrfv2plus_constants.StalenessSeconds, vrfv2plus_constants.GasAfterPaymentCalculation, - vrfv2plus_constants.LinkEthFeedResponse, - vrfv2plus_constants.VRFCoordinatorV2PlusFeeConfig, + vrfv2plus_constants.LinkNativeFeedResponse, + vrfv2plus_constants.VRFCoordinatorV2_5FeeConfig, ) if err != nil { return nil, nil, nil, errors.Wrap(err, ErrSetVRFCoordinatorConfig) } - subID, err := CreateSubAndFindSubID(env, vrfv2PlusContracts.Coordinator) + subID, err := CreateSubAndFindSubID(env, vrfv2_5Contracts.Coordinator) if err != nil { return nil, nil, nil, err } @@ -216,22 +263,22 @@ func SetupVRFV2PlusEnvironment( if err != nil { return nil, nil, nil, errors.Wrap(err, ErrWaitTXsComplete) } - for _, consumer := range vrfv2PlusContracts.LoadTestConsumers { - err = vrfv2PlusContracts.Coordinator.AddConsumer(subID, consumer.Address()) + for _, consumer := range vrfv2_5Contracts.LoadTestConsumers { + err = vrfv2_5Contracts.Coordinator.AddConsumer(subID, consumer.Address()) if err != nil { return nil, nil, nil, errors.Wrap(err, ErrAddConsumerToSub) } } - err = vrfv2PlusContracts.Coordinator.SetLINKAndLINKETHFeed(linkAddress.Address(), mockETHLinkFeedAddress.Address()) + err = vrfv2_5Contracts.Coordinator.SetLINKAndLINKNativeFeed(linkToken.Address(), mockNativeLINKFeed.Address()) if err != nil { - return nil, nil, nil, errors.Wrap(err, ErrSetLinkETHLinkFeed) + return nil, nil, nil, errors.Wrap(err, ErrSetLinkNativeLinkFeed) } err = env.EVMClient.WaitForEvents() if err != nil { return nil, nil, nil, errors.Wrap(err, ErrWaitTXsComplete) } - err = FundSubscription(env, linkAddress, vrfv2PlusContracts.Coordinator, subID) + err = FundSubscription(env, linkToken, vrfv2_5Contracts.Coordinator, subID) if err != nil { return nil, nil, nil, err } @@ -246,11 +293,11 @@ func SetupVRFV2PlusEnvironment( if err != nil { return nil, nil, nil, errors.Wrap(err, ErrNodePrimaryKey) } - provingKey, err := VRFV2PlusRegisterProvingKey(vrfKey, nativeTokenPrimaryKeyAddress, vrfv2PlusContracts.Coordinator) + provingKey, err := VRFV2_5RegisterProvingKey(vrfKey, nativeTokenPrimaryKeyAddress, vrfv2_5Contracts.Coordinator) if err != nil { return nil, nil, nil, errors.Wrap(err, ErrRegisteringProvingKey) } - keyHash, err := vrfv2PlusContracts.Coordinator.HashOfKey(context.Background(), provingKey) + keyHash, err := vrfv2_5Contracts.Coordinator.HashOfKey(context.Background(), provingKey) if err != nil { return nil, nil, nil, errors.Wrap(err, ErrCreatingProvingKeyHash) } @@ -259,7 +306,7 @@ func SetupVRFV2PlusEnvironment( job, err := CreateVRFV2PlusJob( env.GetAPIs()[0], - vrfv2PlusContracts.Coordinator.Address(), + vrfv2_5Contracts.Coordinator.Address(), nativeTokenPrimaryKeyAddress, pubKeyCompressed, chainID.String(), @@ -297,10 +344,97 @@ func SetupVRFV2PlusEnvironment( chainID, } - return vrfv2PlusContracts, subID, &data, nil + return vrfv2_5Contracts, subID, &data, nil } -func CreateSubAndFindSubID(env *test_env.CLClusterTestEnv, coordinator contracts.VRFCoordinatorV2Plus) (*big.Int, error) { +func SetupVRFV2PlusWrapperEnvironment( + env *test_env.CLClusterTestEnv, + linkToken contracts.LinkToken, + mockNativeLINKFeed contracts.MockETHLINKFeed, + coordinator contracts.VRFCoordinatorV2_5, + keyHash [32]byte, + wrapperConsumerContractsAmount int, +) (*VRFV2PlusWrapperContracts, *big.Int, error) { + + wrapperContracts, err := DeployVRFV2PlusDirectFundingContracts( + env.ContractDeployer, + env.EVMClient, + linkToken.Address(), + mockNativeLINKFeed.Address(), + coordinator, + wrapperConsumerContractsAmount, + ) + if err != nil { + return nil, nil, err + } + + err = env.EVMClient.WaitForEvents() + + if err != nil { + return nil, nil, errors.Wrap(err, ErrWaitTXsComplete) + } + + err = wrapperContracts.VRFV2PlusWrapper.SetConfig( + vrfv2plus_constants.WrapperGasOverhead, + vrfv2plus_constants.CoordinatorGasOverhead, + vrfv2plus_constants.WrapperPremiumPercentage, + keyHash, + vrfv2plus_constants.WrapperMaxNumberOfWords, + vrfv2plus_constants.StalenessSeconds, + assets.GWei(50_000_000).ToInt(), + vrfv2plus_constants.VRFCoordinatorV2_5FeeConfig.FulfillmentFlatFeeLinkPPM, + vrfv2plus_constants.VRFCoordinatorV2_5FeeConfig.FulfillmentFlatFeeNativePPM, + ) + if err != nil { + return nil, nil, err + } + + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, errors.Wrap(err, ErrWaitTXsComplete) + } + + //fund sub + wrapperSubID, err := wrapperContracts.VRFV2PlusWrapper.GetSubID(context.Background()) + if err != nil { + return nil, nil, err + } + + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, errors.Wrap(err, ErrWaitTXsComplete) + } + + err = FundSubscription(env, linkToken, coordinator, wrapperSubID) + if err != nil { + return nil, nil, err + } + + //fund consumer with Link + err = linkToken.Transfer( + wrapperContracts.LoadTestConsumers[0].Address(), + big.NewInt(0).Mul(big.NewInt(1e18), vrfv2plus_constants.WrapperConsumerFundingAmountLink), + ) + if err != nil { + return nil, nil, err + } + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, errors.Wrap(err, ErrWaitTXsComplete) + } + + //fund consumer with Eth + err = wrapperContracts.LoadTestConsumers[0].Fund(vrfv2plus_constants.WrapperConsumerFundingAmountNativeToken) + if err != nil { + return nil, nil, err + } + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, errors.Wrap(err, ErrWaitTXsComplete) + } + return wrapperContracts, wrapperSubID, nil +} +func CreateSubAndFindSubID(env *test_env.CLClusterTestEnv, coordinator contracts.VRFCoordinatorV2_5) (*big.Int, error) { err := coordinator.CreateSubscription() if err != nil { return nil, errors.Wrap(err, ErrCreateVRFSubscription) @@ -328,7 +462,7 @@ func GetUpgradedCoordinatorTotalBalance(coordinator contracts.VRFCoordinatorV2Pl return } -func GetCoordinatorTotalBalance(coordinator contracts.VRFCoordinatorV2Plus) (linkTotalBalance *big.Int, nativeTokenTotalBalance *big.Int, err error) { +func GetCoordinatorTotalBalance(coordinator contracts.VRFCoordinatorV2_5) (linkTotalBalance *big.Int, nativeTokenTotalBalance *big.Int, err error) { linkTotalBalance, err = coordinator.GetLinkTotalBalance(context.Background()) if err != nil { return nil, nil, errors.Wrap(err, ErrLinkTotalBalance) @@ -340,14 +474,14 @@ func GetCoordinatorTotalBalance(coordinator contracts.VRFCoordinatorV2Plus) (lin return } -func FundSubscription(env *test_env.CLClusterTestEnv, linkAddress contracts.LinkToken, coordinator contracts.VRFCoordinatorV2Plus, subID *big.Int) error { +func FundSubscription(env *test_env.CLClusterTestEnv, linkAddress contracts.LinkToken, coordinator contracts.VRFCoordinatorV2_5, subID *big.Int) error { //Native Billing - err := coordinator.FundSubscriptionWithEth(subID, big.NewInt(0).Mul(vrfv2plus_constants.VRFSubscriptionFundingAmountNativeToken, big.NewInt(1e18))) + err := coordinator.FundSubscriptionWithNative(subID, big.NewInt(0).Mul(vrfv2plus_constants.VRFSubscriptionFundingAmountNativeToken, big.NewInt(1e18))) if err != nil { return errors.Wrap(err, ErrFundSubWithNativeToken) } - err = FundVRFCoordinatorV2PlusSubscription(linkAddress, coordinator, env.EVMClient, subID, vrfv2plus_constants.VRFSubscriptionFundingAmountLink) + err = FundVRFCoordinatorV2_5Subscription(linkAddress, coordinator, env.EVMClient, subID, vrfv2plus_constants.VRFSubscriptionFundingAmountLink) if err != nil { return errors.Wrap(err, ErrFundSubWithLinkToken) } @@ -361,12 +495,36 @@ func FundSubscription(env *test_env.CLClusterTestEnv, linkAddress contracts.Link func RequestRandomnessAndWaitForFulfillment( consumer contracts.VRFv2PlusLoadTestConsumer, - coordinator contracts.VRFCoordinatorV2Plus, + coordinator contracts.VRFCoordinatorV2_5, + vrfv2PlusData *VRFV2PlusData, + subID *big.Int, + isNativeBilling bool, + l zerolog.Logger, +) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { + _, err := consumer.RequestRandomness( + vrfv2PlusData.KeyHash, + subID, + vrfv2plus_constants.MinimumConfirmations, + vrfv2plus_constants.CallbackGasLimit, + isNativeBilling, + vrfv2plus_constants.NumberOfWords, + vrfv2plus_constants.RandomnessRequestCountPerRequest, + ) + if err != nil { + return nil, errors.Wrap(err, ErrRequestRandomness) + } + + return WaitForRequestAndFulfillmentEvents(consumer.Address(), coordinator, vrfv2PlusData, subID, l) +} + +func RequestRandomnessAndWaitForFulfillmentUpgraded( + consumer contracts.VRFv2PlusLoadTestConsumer, + coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, vrfv2PlusData *VRFV2PlusData, subID *big.Int, isNativeBilling bool, l zerolog.Logger, -) (*vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled, error) { +) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { _, err := consumer.RequestRandomness( vrfv2PlusData.KeyHash, subID, @@ -391,13 +549,13 @@ func RequestRandomnessAndWaitForFulfillment( } l.Debug(). - Interface("Request ID", randomWordsRequestedEvent.RequestId). - Interface("Subscription ID", randomWordsRequestedEvent.SubId). - Interface("Sender Address", randomWordsRequestedEvent.Sender.String()). + Str("Request ID", randomWordsRequestedEvent.RequestId.String()). + Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). + Str("Sender Address", randomWordsRequestedEvent.Sender.String()). Interface("Keyhash", randomWordsRequestedEvent.KeyHash). - Interface("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). - Interface("Number of Words", randomWordsRequestedEvent.NumWords). - Interface("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). + Uint32("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). + Uint32("Number of Words", randomWordsRequestedEvent.NumWords). + Uint16("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). Msg("RandomnessRequested Event") randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( @@ -410,40 +568,62 @@ func RequestRandomnessAndWaitForFulfillment( } l.Debug(). - Interface("Total Payment in Juels", randomWordsFulfilledEvent.Payment). - Interface("TX Hash", randomWordsFulfilledEvent.Raw.TxHash). - Interface("Subscription ID", randomWordsFulfilledEvent.SubID). - Interface("Request ID", randomWordsFulfilledEvent.RequestId). + Str("Total Payment in Juels", randomWordsFulfilledEvent.Payment.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Str("Subscription ID", randomWordsFulfilledEvent.SubID.String()). + Str("Request ID", randomWordsFulfilledEvent.RequestId.String()). Bool("Success", randomWordsFulfilledEvent.Success). Msg("RandomWordsFulfilled Event (TX metadata)") return randomWordsFulfilledEvent, err } -func RequestRandomnessAndWaitForFulfillmentUpgraded( - consumer contracts.VRFv2PlusLoadTestConsumer, - coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, +func DirectFundingRequestRandomnessAndWaitForFulfillment( + consumer contracts.VRFv2PlusWrapperLoadTestConsumer, + coordinator contracts.VRFCoordinatorV2_5, vrfv2PlusData *VRFV2PlusData, subID *big.Int, isNativeBilling bool, l zerolog.Logger, -) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { - _, err := consumer.RequestRandomness( - vrfv2PlusData.KeyHash, - subID, - vrfv2plus_constants.MinimumConfirmations, - vrfv2plus_constants.CallbackGasLimit, - isNativeBilling, - vrfv2plus_constants.NumberOfWords, - vrfv2plus_constants.RandomnessRequestCountPerRequest, - ) +) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { + if isNativeBilling { + _, err := consumer.RequestRandomnessNative( + vrfv2plus_constants.MinimumConfirmations, + vrfv2plus_constants.CallbackGasLimit, + vrfv2plus_constants.NumberOfWords, + vrfv2plus_constants.RandomnessRequestCountPerRequest, + ) + if err != nil { + return nil, errors.Wrap(err, ErrRequestRandomnessDirectFundingNativePayment) + } + } else { + _, err := consumer.RequestRandomness( + vrfv2plus_constants.MinimumConfirmations, + vrfv2plus_constants.CallbackGasLimit, + vrfv2plus_constants.NumberOfWords, + vrfv2plus_constants.RandomnessRequestCountPerRequest, + ) + if err != nil { + return nil, errors.Wrap(err, ErrRequestRandomnessDirectFundingLinkPayment) + } + } + wrapperAddress, err := consumer.GetWrapper(context.Background()) if err != nil { - return nil, errors.Wrap(err, ErrRequestRandomness) + return nil, errors.Wrap(err, "error getting wrapper address") } + return WaitForRequestAndFulfillmentEvents(wrapperAddress.String(), coordinator, vrfv2PlusData, subID, l) +} +func WaitForRequestAndFulfillmentEvents( + consumerAddress string, + coordinator contracts.VRFCoordinatorV2_5, + vrfv2PlusData *VRFV2PlusData, + subID *big.Int, + l zerolog.Logger, +) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( [][32]byte{vrfv2PlusData.KeyHash}, []*big.Int{subID}, - []common.Address{common.HexToAddress(consumer.Address())}, + []common.Address{common.HexToAddress(consumerAddress)}, time.Minute*1, ) if err != nil { @@ -451,13 +631,13 @@ func RequestRandomnessAndWaitForFulfillmentUpgraded( } l.Debug(). - Interface("Request ID", randomWordsRequestedEvent.RequestId). - Interface("Subscription ID", randomWordsRequestedEvent.SubId). - Interface("Sender Address", randomWordsRequestedEvent.Sender.String()). + Str("Request ID", randomWordsRequestedEvent.RequestId.String()). + Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). + Str("Sender Address", randomWordsRequestedEvent.Sender.String()). Interface("Keyhash", randomWordsRequestedEvent.KeyHash). - Interface("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). - Interface("Number of Words", randomWordsRequestedEvent.NumWords). - Interface("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). + Uint32("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). + Uint32("Number of Words", randomWordsRequestedEvent.NumWords). + Uint16("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). Msg("RandomnessRequested Event") randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( @@ -470,10 +650,10 @@ func RequestRandomnessAndWaitForFulfillmentUpgraded( } l.Debug(). - Interface("Total Payment in Juels", randomWordsFulfilledEvent.Payment). - Interface("TX Hash", randomWordsFulfilledEvent.Raw.TxHash). - Interface("Subscription ID", randomWordsFulfilledEvent.SubID). - Interface("Request ID", randomWordsFulfilledEvent.RequestId). + Str("Total Payment in Juels", randomWordsFulfilledEvent.Payment.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Str("Subscription ID", randomWordsFulfilledEvent.SubId.String()). + Str("Request ID", randomWordsFulfilledEvent.RequestId.String()). Bool("Success", randomWordsFulfilledEvent.Success). Msg("RandomWordsFulfilled Event (TX metadata)") return randomWordsFulfilledEvent, err diff --git a/integration-tests/ccip-tests/Makefile b/integration-tests/ccip-tests/Makefile index 05f5ca95e1..454bdccaa9 100644 --- a/integration-tests/ccip-tests/Makefile +++ b/integration-tests/ccip-tests/Makefile @@ -1,3 +1,11 @@ +# example usage: make test_load_ccip_simulated_k8 image=chainlink-ccip tag=latest testimage=chainlink-ccip-tests:latest +.PHONY: test_load_ccip_simulated_k8 +test_load_ccip_simulated_k8: + source ./load-test.env && \ + CHAINLINK_IMAGE=$(image) \ + CHAINLINK_VERSION=$(tag) \ + ENV_JOB_IMAGE=$(testimage) \ + go test -timeout 24h -count=1 -v -run ^TestLoadCCIPStableRequestTriggeringWithNetworkChaos$$ ./load # example usage: make test_smoke_ccip_simulated_local image=chainlink-ccip tag=latest testname=TestSmokeCCIPForBidirectionalLane .PHONY: test_smoke_ccip_simulated_local diff --git a/integration-tests/ccip-tests/actions/ccip_helpers.go b/integration-tests/ccip-tests/actions/ccip_helpers.go index 5a5fb74017..60d2754354 100644 --- a/integration-tests/ccip-tests/actions/ccip_helpers.go +++ b/integration-tests/ccip-tests/actions/ccip_helpers.go @@ -5,7 +5,6 @@ import ( _ "embed" "fmt" "math/big" - "strconv" "strings" "sync" "testing" @@ -39,8 +38,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" - "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/abihelpers" - ccipConfig "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/config" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers" integrationtesthelpers "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/testhelpers/integration" "github.com/smartcontractkit/chainlink/v2/core/store/models" @@ -58,8 +55,8 @@ const ( ChaosGroupCCIPGeth = "CCIPGeth" // both source and destination simulated geth networks ChaosGroupNetworkACCIPGeth = "CCIPNetworkAGeth" ChaosGroupNetworkBCCIPGeth = "CCIPNetworkBGeth" - RootSnoozeTimeSimulated = 1 * time.Minute - InflightExpirySimulated = 1 * time.Minute + RootSnoozeTimeSimulated = 3 * time.Minute + InflightExpirySimulated = 3 * time.Minute // we keep the finality timeout high as it's out of our control FinalityTimeout = 1 * time.Hour TokenTransfer string = "WithToken" @@ -577,8 +574,7 @@ type SourceCCIPModule struct { DestNetworkName string OnRamp *contracts.OnRamp SrcStartBlock uint64 - CCIPSendRequestedWatcherMu *sync.Mutex - CCIPSendRequestedWatcher map[string]*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested + CCIPSendRequestedWatcher sync.Map // map[string]*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested NewFinalizedBlockNum atomic.Uint64 NewFinalizedBlockTimestamp atomic.Time } @@ -655,7 +651,9 @@ func (sourceCCIP *SourceCCIPModule) DeployContracts(lane *laneconfig.LaneConfig) }) tokenTransferFeeConfig = append(tokenTransferFeeConfig, evm_2_evm_onramp.EVM2EVMOnRampTokenTransferFeeConfigArgs{ Token: token.ContractAddress, - Ratio: 5_0, // 5 bps + MinFeeUSD: 50, // $0.5 + MaxFeeUSD: 1_000_000_00, // $ 1 million + Ratio: 5_0, // 5 bps DestGasOverhead: 34_000, DestBytesOverhead: 0, }) @@ -676,22 +674,18 @@ func (sourceCCIP *SourceCCIPModule) DeployContracts(lane *laneconfig.LaneConfig) sourceCCIP.Common.RateLimiterConfig, []evm_2_evm_onramp.EVM2EVMOnRampFeeTokenConfigArgs{ { - Token: common.HexToAddress(sourceCCIP.Common.FeeToken.Address()), - NetworkFeeUSD: 1_00, - MinTokenTransferFeeUSD: 1_00, - MaxTokenTransferFeeUSD: 5000_00, - GasMultiplier: GasFeeMultiplier, - PremiumMultiplier: 1e18, - Enabled: true, + Token: common.HexToAddress(sourceCCIP.Common.FeeToken.Address()), + NetworkFeeUSD: 1_00, + GasMultiplier: GasFeeMultiplier, + PremiumMultiplier: 1e18, + Enabled: true, }, { - Token: sourceCCIP.Common.WrappedNative, - NetworkFeeUSD: 1_00, - MinTokenTransferFeeUSD: 1_00, - MaxTokenTransferFeeUSD: 5000_00, - GasMultiplier: GasFeeMultiplier, - PremiumMultiplier: 1e18, - Enabled: true, + Token: sourceCCIP.Common.WrappedNative, + NetworkFeeUSD: 1_00, + GasMultiplier: GasFeeMultiplier, + PremiumMultiplier: 1e18, + Enabled: true, }, }, tokenTransferFeeConfig, @@ -833,11 +827,10 @@ func (sourceCCIP *SourceCCIPModule) UpdateBalance( func (sourceCCIP *SourceCCIPModule) AssertSendRequestedLogFinalized( lggr zerolog.Logger, - reqNo int64, seqNum uint64, SendRequested *evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested, prevEventAt time.Time, - reports *testreporters.CCIPLaneStats, + reqStat *testreporters.RequestStat, ) (time.Time, uint64, error) { if sourceCCIP.Common.ChainClient.NetworkSimulated() { return prevEventAt, 0, nil @@ -845,10 +838,10 @@ func (sourceCCIP *SourceCCIPModule) AssertSendRequestedLogFinalized( lggr.Info().Msg("Waiting for CCIPSendRequested event log to be finalized") finalizedBlockNum, finalizedAt, err := sourceCCIP.Common.ChainClient.WaitForFinalizedTx(SendRequested.Raw.TxHash) if err != nil { - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.SourceLogFinalized, time.Since(prevEventAt), testreporters.Failure) + reqStat.UpdateState(lggr, seqNum, testreporters.SourceLogFinalized, time.Since(prevEventAt), testreporters.Failure) return time.Time{}, 0, fmt.Errorf("error waiting for CCIPSendRequested event log to be finalized - %+v", err) } - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.SourceLogFinalized, finalizedAt.Sub(prevEventAt), testreporters.Success, + reqStat.UpdateState(lggr, seqNum, testreporters.SourceLogFinalized, finalizedAt.Sub(prevEventAt), testreporters.Success, testreporters.TransactionStats{ TxHash: SendRequested.Raw.TxHash.Hex(), FinalizedByBlock: finalizedBlockNum.String(), @@ -859,11 +852,10 @@ func (sourceCCIP *SourceCCIPModule) AssertSendRequestedLogFinalized( func (sourceCCIP *SourceCCIPModule) AssertEventCCIPSendRequested( lggr zerolog.Logger, - reqNo int64, txHash string, timeout time.Duration, prevEventAt time.Time, - reports *testreporters.CCIPLaneStats, + reqStat *testreporters.RequestStat, ) (*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested, time.Time, error) { lggr.Info().Msg("Waiting for CCIPSendRequested event") ticker := time.NewTicker(time.Second) @@ -874,22 +866,20 @@ func (sourceCCIP *SourceCCIPModule) AssertEventCCIPSendRequested( for { select { case <-ticker.C: - sourceCCIP.CCIPSendRequestedWatcherMu.Lock() - sendRequested, ok := sourceCCIP.CCIPSendRequestedWatcher[txHash] - sourceCCIP.CCIPSendRequestedWatcherMu.Unlock() - if ok && sendRequested != nil { - hdr, err := sourceCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(sendRequested.Raw.BlockNumber))) - receivedAt := time.Now().UTC() - if err == nil { - receivedAt = hdr.Timestamp + value, ok := sourceCCIP.CCIPSendRequestedWatcher.Load(txHash) + if ok { + if sendRequestedEvent, exists := value.(*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested); exists { + // if the value is processed, delete it from the map + sourceCCIP.CCIPSendRequestedWatcher.Delete(txHash) + sentMsg := sendRequestedEvent.Message + seqNum := sentMsg.SequenceNumber + // prevEventAt is the time when the message was successful, this should be same as the time when the event was emitted + reqStat.UpdateState(lggr, seqNum, testreporters.CCIPSendRe, 0, testreporters.Success) + return sendRequestedEvent, prevEventAt, nil } - sentMsg := sendRequested.Message - seqNum := sentMsg.SequenceNumber - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.CCIPSendRe, receivedAt.Sub(prevEventAt), testreporters.Success) - return sendRequested, receivedAt, nil } case <-ctx.Done(): - reports.UpdatePhaseStats(reqNo, 0, testreporters.CCIPSendRe, time.Since(prevEventAt), testreporters.Failure) + reqStat.UpdateState(lggr, 0, testreporters.CCIPSendRe, time.Since(prevEventAt), testreporters.Failure) return nil, time.Now(), fmt.Errorf("CCIPSendRequested event is not found for tx %s", txHash) } } @@ -948,12 +938,12 @@ func (sourceCCIP *SourceCCIPModule) SendRequest( // initiate the transfer // if the token address is 0x0 it will use Native as fee token and the fee amount should be mentioned in bind.TransactOpts's value if feeToken != common.HexToAddress("0x0") { - sendTx, err = sourceCCIP.Common.Router.CCIPSend(destChainSelector, msg, nil) + sendTx, err = sourceCCIP.Common.Router.CCIPSendAndProcessTx(destChainSelector, msg, nil) if err != nil { return common.Hash{}, time.Since(timeNow), nil, fmt.Errorf("failed initiating the transfer ccip-send: %+v", err) } } else { - sendTx, err = sourceCCIP.Common.Router.CCIPSend(destChainSelector, msg, fee) + sendTx, err = sourceCCIP.Common.Router.CCIPSendAndProcessTx(destChainSelector, msg, fee) if err != nil { return common.Hash{}, time.Since(timeNow), nil, fmt.Errorf("failed initiating the transfer ccip-send: %+v", err) } @@ -973,13 +963,11 @@ func DefaultSourceCCIPModule(logger zerolog.Logger, chainClient blockchain.EVMCl return nil, err } return &SourceCCIPModule{ - Common: cmn, - TransferAmount: transferAmount, - DestinationChainId: destChainId, - DestNetworkName: destChain, - Sender: common.HexToAddress(chainClient.GetDefaultWallet().Address()), - CCIPSendRequestedWatcher: make(map[string]*evm_2_evm_onramp.EVM2EVMOnRampCCIPSendRequested), - CCIPSendRequestedWatcherMu: &sync.Mutex{}, + Common: cmn, + TransferAmount: transferAmount, + DestinationChainId: destChainId, + DestNetworkName: destChain, + Sender: common.HexToAddress(chainClient.GetDefaultWallet().Address()), }, nil } @@ -991,12 +979,9 @@ type DestCCIPModule struct { ReceiverDapp *contracts.ReceiverDapp OffRamp *contracts.OffRamp WrappedNative common.Address - ReportAcceptedWatcherMu *sync.Mutex - ReportAcceptedWatcher map[uint64]*commit_store.CommitStoreReportAccepted - ExecStateChangedMu *sync.Mutex - ExecStateChangedWatcher map[uint64]*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged - ReportBlessedWatcherMu *sync.Mutex - ReportBlessedWatcher map[[32]byte]*types.Log + ReportAcceptedWatcher sync.Map + ExecStateChangedWatcher sync.Map + ReportBlessedWatcher sync.Map NextSeqNumToCommit *atomic.Uint64 } @@ -1214,11 +1199,10 @@ func (destCCIP *DestCCIPModule) UpdateBalance( func (destCCIP *DestCCIPModule) AssertEventExecutionStateChanged( lggr zerolog.Logger, - reqNo int64, seqNum uint64, timeout time.Duration, timeNow time.Time, - reports *testreporters.CCIPLaneStats, + reqStat *testreporters.RequestStat, ) error { lggr.Info().Int64("seqNum", int64(seqNum)).Msg("Waiting for ExecutionStateChanged event") ctx, cancel := context.WithTimeout(context.Background(), timeout) @@ -1227,36 +1211,43 @@ func (destCCIP *DestCCIPModule) AssertEventExecutionStateChanged( for { select { case <-ticker.C: - destCCIP.ExecStateChangedMu.Lock() - e, ok := destCCIP.ExecStateChangedWatcher[seqNum] - destCCIP.ExecStateChangedMu.Unlock() - if ok && e != nil { - vLogs := e.Raw - receivedAt := time.Now().UTC() - hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(vLogs.BlockNumber))) - if err == nil { - receivedAt = hdr.Timestamp - } - receipt, err := destCCIP.Common.ChainClient.GetTxReceipt(vLogs.TxHash) - if err != nil { - lggr.Warn().Msg("Failed to get receipt for ExecStateChanged event") - } - if abihelpers.MessageExecutionState(e.State) == abihelpers.ExecutionStateSuccess { - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.ExecStateChanged, receivedAt.Sub(timeNow), - testreporters.Success, - testreporters.TransactionStats{ - TxHash: vLogs.TxHash.Hex(), - GasUsed: receipt.GasUsed, - }) - return nil - } else { - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.ExecStateChanged, time.Since(timeNow), testreporters.Failure) - return fmt.Errorf("ExecutionStateChanged event state changed to %d with data %x for seq num %v for lane %d-->%d", - e.State, e.ReturnData, seqNum, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + value, ok := destCCIP.ExecStateChangedWatcher.Load(seqNum) + if ok && value != nil { + e, exists := value.(*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged) + if exists { + // if the value is processed, delete it from the map + destCCIP.ExecStateChangedWatcher.Delete(seqNum) + vLogs := e.Raw + receivedAt := time.Now().UTC() + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(vLogs.BlockNumber))) + if err == nil { + receivedAt = hdr.Timestamp + } + receipt, err := destCCIP.Common.ChainClient.GetTxReceipt(vLogs.TxHash) + if err != nil { + lggr.Warn().Msg("Failed to get receipt for ExecStateChanged event") + } + var gasUsed uint64 + if receipt != nil { + gasUsed = receipt.GasUsed + } + if testhelpers.MessageExecutionState(e.State) == testhelpers.ExecutionStateSuccess { + reqStat.UpdateState(lggr, seqNum, testreporters.ExecStateChanged, receivedAt.Sub(timeNow), + testreporters.Success, + testreporters.TransactionStats{ + TxHash: vLogs.TxHash.Hex(), + GasUsed: gasUsed, + }) + return nil + } else { + reqStat.UpdateState(lggr, seqNum, testreporters.ExecStateChanged, time.Since(timeNow), testreporters.Failure) + return fmt.Errorf("ExecutionStateChanged event state changed to %d with data %x for seq num %v for lane %d-->%d", + e.State, e.ReturnData, seqNum, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) + } } } case <-ctx.Done(): - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.ExecStateChanged, time.Since(timeNow), testreporters.Failure) + reqStat.UpdateState(lggr, seqNum, testreporters.ExecStateChanged, time.Since(timeNow), testreporters.Failure) return fmt.Errorf("ExecutionStateChanged event not found for seq num %v for lane %d-->%d", seqNum, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) } @@ -1265,11 +1256,10 @@ func (destCCIP *DestCCIPModule) AssertEventExecutionStateChanged( func (destCCIP *DestCCIPModule) AssertEventReportAccepted( lggr zerolog.Logger, - reqNo int64, seqNum uint64, timeout time.Duration, prevEventAt time.Time, - reports *testreporters.CCIPLaneStats, + reqStat *testreporters.RequestStat, ) (*commit_store.CommitStoreCommitReport, time.Time, error) { lggr.Info().Int64("seqNum", int64(seqNum)).Msg("Waiting for ReportAccepted event") ctx, cancel := context.WithTimeout(context.Background(), timeout) @@ -1278,44 +1268,51 @@ func (destCCIP *DestCCIPModule) AssertEventReportAccepted( for { select { case <-ticker.C: - destCCIP.ReportAcceptedWatcherMu.Lock() - reportAccepted, ok := destCCIP.ReportAcceptedWatcher[seqNum] - destCCIP.ReportAcceptedWatcherMu.Unlock() - if ok && reportAccepted != nil { - receivedAt := time.Now().UTC() - hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(reportAccepted.Raw.BlockNumber))) - if err == nil { - receivedAt = hdr.Timestamp - } - - totalTime := receivedAt.Sub(prevEventAt) - // we cannot calculate the exact time at which block was finalized - // as a result sometimes we get a time which is slightly after the block was marked as finalized - // in such cases we get a negative time difference between finalized and report accepted if the commit - // has happened almost immediately after block being finalized - // in such cases we set the time difference to 1 second - if totalTime < 0 { - lggr.Warn(). - Uint64("seqNum", seqNum). - Time("finalized at", prevEventAt). - Time("ReportAccepted at", receivedAt). - Msg("ReportAccepted event received before finalized timestamp") - totalTime = time.Second - } - receipt, err := destCCIP.Common.ChainClient.GetTxReceipt(reportAccepted.Raw.TxHash) - if err != nil { - lggr.Warn().Msg("Failed to get receipt for ReportAccepted event") + value, ok := destCCIP.ReportAcceptedWatcher.Load(seqNum) + if ok && value != nil { + reportAccepted, exists := value.(*commit_store.CommitStoreReportAccepted) + if exists { + // if the value is processed, delete it from the map + destCCIP.ReportAcceptedWatcher.Delete(seqNum) + receivedAt := time.Now().UTC() + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(reportAccepted.Raw.BlockNumber))) + if err == nil { + receivedAt = hdr.Timestamp + } + + totalTime := receivedAt.Sub(prevEventAt) + // we cannot calculate the exact time at which block was finalized + // as a result sometimes we get a time which is slightly after the block was marked as finalized + // in such cases we get a negative time difference between finalized and report accepted if the commit + // has happened almost immediately after block being finalized + // in such cases we set the time difference to 1 second + if totalTime < 0 { + lggr.Warn(). + Uint64("seqNum", seqNum). + Time("finalized at", prevEventAt). + Time("ReportAccepted at", receivedAt). + Msg("ReportAccepted event received before finalized timestamp") + totalTime = time.Second + } + receipt, err := destCCIP.Common.ChainClient.GetTxReceipt(reportAccepted.Raw.TxHash) + if err != nil { + lggr.Warn().Msg("Failed to get receipt for ReportAccepted event") + } + var gasUsed uint64 + if receipt != nil { + gasUsed = receipt.GasUsed + } + reqStat.UpdateState(lggr, seqNum, testreporters.Commit, totalTime, testreporters.Success, + testreporters.TransactionStats{ + GasUsed: gasUsed, + TxHash: reportAccepted.Raw.TxHash.String(), + CommitRoot: fmt.Sprintf("%x", reportAccepted.Report.MerkleRoot), + }) + return &reportAccepted.Report, receivedAt, nil } - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.Commit, totalTime, testreporters.Success, - testreporters.TransactionStats{ - GasUsed: receipt.GasUsed, - TxHash: reportAccepted.Raw.TxHash.String(), - CommitRoot: fmt.Sprintf("%x", reportAccepted.Report.MerkleRoot), - }) - return &reportAccepted.Report, receivedAt, nil } case <-ctx.Done(): - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.Commit, time.Since(prevEventAt), testreporters.Failure) + reqStat.UpdateState(lggr, seqNum, testreporters.Commit, time.Since(prevEventAt), testreporters.Failure) return nil, time.Now().UTC(), fmt.Errorf("ReportAccepted is not found for seq num %d lane %d-->%d", seqNum, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) } @@ -1324,12 +1321,11 @@ func (destCCIP *DestCCIPModule) AssertEventReportAccepted( func (destCCIP *DestCCIPModule) AssertReportBlessed( lggr zerolog.Logger, - reqNo int64, seqNum uint64, timeout time.Duration, CommitReport commit_store.CommitStoreCommitReport, prevEventAt time.Time, - reports *testreporters.CCIPLaneStats, + reqStat *testreporters.RequestStat, ) (time.Time, error) { if destCCIP.Common.ARM == nil { lggr.Info().Interface("commit store interval", CommitReport.Interval).Hex("Root", CommitReport.MerkleRoot[:]).Msg("Skipping ReportBlessed check for mock ARM") @@ -1342,29 +1338,36 @@ func (destCCIP *DestCCIPModule) AssertReportBlessed( for { select { case <-ticker.C: - destCCIP.ReportBlessedWatcherMu.Lock() - vLogs, ok := destCCIP.ReportBlessedWatcher[CommitReport.MerkleRoot] - destCCIP.ReportBlessedWatcherMu.Unlock() + value, ok := destCCIP.ReportBlessedWatcher.Load(CommitReport.MerkleRoot) receivedAt := time.Now().UTC() - if ok && vLogs != nil { - hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(vLogs.BlockNumber))) - if err == nil { - receivedAt = hdr.Timestamp - } - receipt, err := destCCIP.Common.ChainClient.GetTxReceipt(vLogs.TxHash) - if err != nil { - lggr.Fatal().Err(err).Msg("Failed to get receipt for ReportBlessed event") + if ok && value != nil { + vLogs, exists := value.(*types.Log) + if exists { + // if the value is processed, delete it from the map + destCCIP.ReportBlessedWatcher.Delete(CommitReport.MerkleRoot) + hdr, err := destCCIP.Common.ChainClient.HeaderByNumber(ctx, big.NewInt(int64(vLogs.BlockNumber))) + if err == nil { + receivedAt = hdr.Timestamp + } + receipt, err := destCCIP.Common.ChainClient.GetTxReceipt(vLogs.TxHash) + if err != nil { + lggr.Warn().Err(err).Msg("Failed to get receipt for ReportBlessed event") + } + var gasUsed uint64 + if receipt != nil { + gasUsed = receipt.GasUsed + } + reqStat.UpdateState(lggr, seqNum, testreporters.ReportBlessed, receivedAt.Sub(prevEventAt), testreporters.Success, + testreporters.TransactionStats{ + GasUsed: gasUsed, + TxHash: vLogs.TxHash.String(), + CommitRoot: fmt.Sprintf("%x", CommitReport.MerkleRoot), + }) + return receivedAt, nil } - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.ReportBlessed, receivedAt.Sub(prevEventAt), testreporters.Success, - testreporters.TransactionStats{ - GasUsed: receipt.GasUsed, - TxHash: vLogs.TxHash.String(), - CommitRoot: fmt.Sprintf("%x", CommitReport.MerkleRoot), - }) - return receivedAt, nil } case <-ctx.Done(): - reports.UpdatePhaseStats(reqNo, seqNum, testreporters.ReportBlessed, time.Since(prevEventAt), testreporters.Failure) + reqStat.UpdateState(lggr, seqNum, testreporters.ReportBlessed, time.Since(prevEventAt), testreporters.Failure) return time.Now().UTC(), fmt.Errorf("ReportBlessed is not found for interval %+v lane %d-->%d", CommitReport.Interval, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) } @@ -1373,11 +1376,10 @@ func (destCCIP *DestCCIPModule) AssertReportBlessed( func (destCCIP *DestCCIPModule) AssertSeqNumberExecuted( lggr zerolog.Logger, - reqNo int64, seqNumberBefore uint64, timeout time.Duration, timeNow time.Time, - reports *testreporters.CCIPLaneStats, + reqStat *testreporters.RequestStat, ) error { lggr.Info().Int64("seqNum", int64(seqNumberBefore)).Msg("Waiting to be executed") ctx, cancel := context.WithTimeout(context.Background(), timeout) @@ -1391,7 +1393,7 @@ func (destCCIP *DestCCIPModule) AssertSeqNumberExecuted( } seqNumberAfter, err := destCCIP.CommitStore.Instance.GetExpectedNextSequenceNumber(nil) if err != nil { - reports.UpdatePhaseStats(reqNo, seqNumberBefore, testreporters.Commit, time.Since(timeNow), testreporters.Failure) + reqStat.UpdateState(lggr, seqNumberBefore, testreporters.Commit, time.Since(timeNow), testreporters.Failure) return fmt.Errorf("error %+v in GetNextExpectedSeqNumber by commitStore for seqNum %d lane %d-->%d", err, seqNumberBefore+1, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) } @@ -1400,7 +1402,7 @@ func (destCCIP *DestCCIPModule) AssertSeqNumberExecuted( return nil } case <-ctx.Done(): - reports.UpdatePhaseStats(reqNo, seqNumberBefore, testreporters.Commit, time.Since(timeNow), testreporters.Failure) + reqStat.UpdateState(lggr, seqNumberBefore, testreporters.Commit, time.Since(timeNow), testreporters.Failure) return fmt.Errorf("sequence number is not increased for seq num %d lane %d-->%d", seqNumberBefore, destCCIP.SourceChainId, destCCIP.Common.ChainClient.GetChainID()) } @@ -1413,22 +1415,17 @@ func DefaultDestinationCCIPModule(logger zerolog.Logger, chainClient blockchain. return nil, err } return &DestCCIPModule{ - Common: cmn, - SourceChainId: sourceChainId, - SourceNetworkName: sourceChain, - ReportAcceptedWatcherMu: &sync.Mutex{}, - ReportAcceptedWatcher: make(map[uint64]*commit_store.CommitStoreReportAccepted), - ExecStateChangedMu: &sync.Mutex{}, - ExecStateChangedWatcher: make(map[uint64]*evm_2_evm_offramp.EVM2EVMOffRampExecutionStateChanged), - ReportBlessedWatcherMu: &sync.Mutex{}, - ReportBlessedWatcher: make(map[[32]byte]*types.Log), - NextSeqNumToCommit: atomic.NewUint64(1), + Common: cmn, + SourceChainId: sourceChainId, + SourceNetworkName: sourceChain, + NextSeqNumToCommit: atomic.NewUint64(1), }, nil } type CCIPRequest struct { txHash string txConfirmationTimestamp time.Time + RequestStat *testreporters.RequestStat } func CCIPRequestFromTxHash(txHash common.Hash, chainClient blockchain.EVMClient) (CCIPRequest, *types.Receipt, error) { @@ -1546,11 +1543,12 @@ func (lane *CCIPLane) RecordStateBeforeTransfer() { lane.SentReqs = make(map[int64]CCIPRequest) } -func (lane *CCIPLane) AddToSentReqs(txHash common.Hash) (*types.Receipt, error) { +func (lane *CCIPLane) AddToSentReqs(txHash common.Hash, reqStat *testreporters.RequestStat) (*types.Receipt, error) { request, rcpt, err := CCIPRequestFromTxHash(txHash, lane.Source.Common.ChainClient) if err != nil { return rcpt, fmt.Errorf("could not get request from tx hash %s: %+v", txHash.Hex(), err) } + request.RequestStat = reqStat lane.SentReqs[int64(lane.NumberOfReq+1)] = request lane.NumberOfReq++ return rcpt, nil @@ -1559,19 +1557,20 @@ func (lane *CCIPLane) AddToSentReqs(txHash common.Hash) (*types.Receipt, error) func (lane *CCIPLane) SendRequests(noOfRequests int, msgType string) error { for i := 1; i <= noOfRequests; i++ { msg := fmt.Sprintf("msg %d", i) + stat := testreporters.NewCCIPRequestStats(int64(lane.NumberOfReq + i)) txHash, txConfirmationDur, fee, err := lane.Source.SendRequest( lane.Dest.ReceiverDapp.EthAddress, msgType, msg, common.HexToAddress(lane.Source.Common.FeeToken.Address()), ) if err != nil { - lane.Reports.UpdatePhaseStats(int64(lane.NumberOfReq+i), 0, + stat.UpdateState(lane.Logger, 0, testreporters.TX, txConfirmationDur, testreporters.Failure) return fmt.Errorf("could not send request: %+v", err) } err = lane.Source.Common.ChainClient.WaitForEvents() if err != nil { - lane.Reports.UpdatePhaseStats(int64(lane.NumberOfReq+i), 0, + stat.UpdateState(lane.Logger, 0, testreporters.TX, txConfirmationDur, testreporters.Failure) return fmt.Errorf("could not send request: %+v", err) } @@ -1580,16 +1579,20 @@ func (lane *CCIPLane) SendRequests(noOfRequests int, msgType string) error { if msgType == DataOnlyTransfer { noOfTokens = 0 } - rcpt, err := lane.AddToSentReqs(txHash) + rcpt, err := lane.AddToSentReqs(txHash, stat) if err != nil { - lane.Reports.UpdatePhaseStats(int64(lane.NumberOfReq+i), 0, + stat.UpdateState(lane.Logger, 0, testreporters.TX, txConfirmationDur, testreporters.Failure) return err } - lane.Reports.UpdatePhaseStats(int64(lane.NumberOfReq+i), 0, + var gasUsed uint64 + if rcpt != nil { + gasUsed = rcpt.GasUsed + } + stat.UpdateState(lane.Logger, 0, testreporters.TX, txConfirmationDur, testreporters.Success, testreporters.TransactionStats{ Fee: fee.String(), - GasUsed: rcpt.GasUsed, + GasUsed: gasUsed, TxHash: txHash.Hex(), NoOfTokensSent: noOfTokens, MessageBytesLength: len([]byte(msg)), @@ -1613,35 +1616,38 @@ func (lane *CCIPLane) ValidateRequests() { } } -func (lane *CCIPLane) ValidateRequestByTxHash(txHash string, txConfirmattion time.Time, reqNo int64) error { +func (lane *CCIPLane) ValidateRequestByTxHash(txHash string, txConfirmation time.Time, reqNo int64) error { + reqStat := lane.SentReqs[reqNo].RequestStat + defer lane.Reports.UpdatePhaseStatsForReq(reqStat) msgLog, ccipSendReqGenAt, err := lane.Source.AssertEventCCIPSendRequested( - lane.Logger, reqNo, txHash, lane.ValidationTimeout, txConfirmattion, lane.Reports) + lane.Logger, txHash, lane.ValidationTimeout, txConfirmation, reqStat) if err != nil || msgLog == nil { return fmt.Errorf("could not validate CCIPSendRequested event: %+v", err) } seqNumber := msgLog.Message.SequenceNumber - sourceLogFinalizedAt, _, err := lane.Source.AssertSendRequestedLogFinalized(lane.Logger, reqNo, seqNumber, msgLog, ccipSendReqGenAt, lane.Reports) + sourceLogFinalizedAt, _, err := lane.Source.AssertSendRequestedLogFinalized(lane.Logger, seqNumber, msgLog, ccipSendReqGenAt, reqStat) if err != nil { return fmt.Errorf("could not finalize CCIPSendRequested event: %+v", err) } - err = lane.Dest.AssertSeqNumberExecuted(lane.Logger, reqNo, seqNumber, lane.ValidationTimeout, sourceLogFinalizedAt, lane.Reports) + err = lane.Dest.AssertSeqNumberExecuted(lane.Logger, seqNumber, lane.ValidationTimeout, sourceLogFinalizedAt, reqStat) if err != nil { return fmt.Errorf("could not validate seq number increase at commit store: %+v", err) } // Verify whether commitStore has accepted the report - commitReport, reportAcceptedAt, err := lane.Dest.AssertEventReportAccepted(lane.Logger, reqNo, seqNumber, lane.ValidationTimeout, sourceLogFinalizedAt, lane.Reports) + commitReport, reportAcceptedAt, err := lane.Dest.AssertEventReportAccepted( + lane.Logger, seqNumber, lane.ValidationTimeout, sourceLogFinalizedAt, reqStat) if err != nil || commitReport == nil { return fmt.Errorf("could not validate ReportAccepted event: %+v", err) } - reportBlessedAt, err := lane.Dest.AssertReportBlessed(lane.Logger, reqNo, seqNumber, lane.ValidationTimeout, *commitReport, reportAcceptedAt, lane.Reports) + reportBlessedAt, err := lane.Dest.AssertReportBlessed(lane.Logger, seqNumber, lane.ValidationTimeout, *commitReport, reportAcceptedAt, reqStat) if err != nil { return fmt.Errorf("could not validate ReportBlessed event: %+v", err) } // Verify whether the execution state is changed and the transfer is successful - err = lane.Dest.AssertEventExecutionStateChanged(lane.Logger, reqNo, seqNumber, lane.ValidationTimeout, reportBlessedAt, lane.Reports) + err = lane.Dest.AssertEventExecutionStateChanged(lane.Logger, seqNumber, lane.ValidationTimeout, reportBlessedAt, reqStat) if err != nil { return fmt.Errorf("could not validate ExecutionStateChanged event: %+v", err) } @@ -1667,9 +1673,7 @@ func (lane *CCIPLane) StartEventWatchers() error { for { e := <-sendReqEvent lane.Logger.Info().Msgf("CCIPSendRequested event received for seq number %d", e.Message.SequenceNumber) - lane.Source.CCIPSendRequestedWatcherMu.Lock() - lane.Source.CCIPSendRequestedWatcher[e.Raw.TxHash.Hex()] = e - lane.Source.CCIPSendRequestedWatcherMu.Unlock() + lane.Source.CCIPSendRequestedWatcher.Store(e.Raw.TxHash.Hex(), e) } }() reportAcceptedEvent := make(chan *commit_store.CommitStoreReportAccepted) @@ -1683,11 +1687,9 @@ func (lane *CCIPLane) StartEventWatchers() error { go func() { for { e := <-reportAcceptedEvent - lane.Dest.ReportAcceptedWatcherMu.Lock() for i := e.Report.Interval.Min; i <= e.Report.Interval.Max; i++ { - lane.Dest.ReportAcceptedWatcher[i] = e + lane.Dest.ReportAcceptedWatcher.Store(i, e) } - lane.Dest.ReportAcceptedWatcherMu.Unlock() } }() @@ -1704,11 +1706,9 @@ func (lane *CCIPLane) StartEventWatchers() error { for { e := <-reportBlessedEvent lane.Logger.Info().Msgf("TaggedRootBlessed event received for root %x", e.TaggedRoot.Root) - lane.Dest.ReportBlessedWatcherMu.Lock() if e.TaggedRoot.CommitStore == lane.Dest.CommitStore.EthAddress { - lane.Dest.ReportBlessedWatcher[e.TaggedRoot.Root] = &e.Raw + lane.Dest.ReportBlessedWatcher.Store(e.TaggedRoot.Root, &e.Raw) } - lane.Dest.ReportBlessedWatcherMu.Unlock() } }() } @@ -1724,9 +1724,7 @@ func (lane *CCIPLane) StartEventWatchers() error { for { e := <-execStateChangedEvent lane.Logger.Info().Msgf("Execution state changed event received for seq number %d", e.SequenceNumber) - lane.Dest.ExecStateChangedMu.Lock() - lane.Dest.ExecStateChangedWatcher[e.SequenceNumber] = e - lane.Dest.ExecStateChangedMu.Unlock() + lane.Dest.ExecStateChangedWatcher.Store(e.SequenceNumber, e) } }() return nil @@ -1949,16 +1947,21 @@ func SetOCR2Configs(commitNodes, execNodes []*client.CLNodesWithKeys, destCCIP D rootSnooze = models.MustMakeDuration(RootSnoozeTimeSimulated) inflightExpiry = models.MustMakeDuration(InflightExpirySimulated) } - signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err := contracts.NewOffChainAggregatorV2Config(commitNodes, ccipConfig.CommitOffchainConfig{ - SourceFinalityDepth: 1, - DestFinalityDepth: 1, - FeeUpdateHeartBeat: models.MustMakeDuration(10 * time.Second), // reduce the heartbeat to 10 sec for faster fee updates - FeeUpdateDeviationPPB: 1e6, - MaxGasPrice: 200e9, - InflightCacheExpiry: inflightExpiry, - }, ccipConfig.CommitOnchainConfig{ - PriceRegistry: destCCIP.Common.PriceRegistry.EthAddress, - }) + + signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err := contracts.NewOffChainAggregatorV2ConfigForCCIPPlugin( + commitNodes, testhelpers.NewCommitOffchainConfig( + 1, + 1, + models.MustMakeDuration(10*time.Second), // reduce the heartbeat to 10 sec for faster fee updates + 1e6, + 1e6, + models.MustMakeDuration(10*time.Second), + 1e6, + 200e9, + inflightExpiry, + ), testhelpers.NewCommitOnchainConfig( + destCCIP.Common.PriceRegistry.EthAddress, + ), contracts.OCR2ParamsForCommit, 3*time.Minute) if err != nil { return errors.WithStack(err) } @@ -1974,22 +1977,24 @@ func SetOCR2Configs(commitNodes, execNodes []*client.CLNodesWithKeys, destCCIP D nodes = execNodes } if destCCIP.OffRamp != nil { - signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err = contracts.NewOffChainAggregatorV2Config(nodes, ccipConfig.ExecOffchainConfig{ - SourceFinalityDepth: 1, - DestOptimisticConfirmations: 1, - DestFinalityDepth: 1, - BatchGasLimit: 5_000_000, - RelativeBoostPerWaitHour: 0.7, - MaxGasPrice: 200e9, - InflightCacheExpiry: inflightExpiry, - RootSnoozeTime: rootSnooze, - }, ccipConfig.ExecOnchainConfig{ - PermissionLessExecutionThresholdSeconds: 60 * 30, - Router: destCCIP.Common.Router.EthAddress, - PriceRegistry: destCCIP.Common.PriceRegistry.EthAddress, - MaxTokensLength: 5, - MaxDataSize: 50000, - }) + signers, transmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, err = contracts.NewOffChainAggregatorV2ConfigForCCIPPlugin( + nodes, testhelpers.NewExecOffchainConfig( + 1, + 1, + 1, + 5_000_000, + 0.7, + 200e9, + inflightExpiry, + rootSnooze, + ), testhelpers.NewExecOnchainConfig( + 60*30, + destCCIP.Common.Router.EthAddress, + destCCIP.Common.PriceRegistry.EthAddress, + 5, + 50000, + ), contracts.OCR2ParamsForExec, 3*time.Minute) + if err != nil { return errors.WithStack(err) } @@ -2164,8 +2169,12 @@ func (c *CCIPTestEnv) ChaosLabelForGeth(t *testing.T, srcChain, destChain string "app": GethLabel(destChain), }, ChaosGroupNetworkBCCIPGeth) require.NoError(t, err) - gethNetworksLabels := []string{GethLabel(srcChain), GethLabel(destChain)} + c.ChaosLabelForAllGeth(t, gethNetworksLabels) + +} + +func (c *CCIPTestEnv) ChaosLabelForAllGeth(t *testing.T, gethNetworksLabels []string) { for _, gethNetworkLabel := range gethNetworksLabels { err := c.K8Env.Client.AddLabel(c.K8Env.Cfg.Namespace, fmt.Sprintf("app=%s", gethNetworkLabel), @@ -2178,7 +2187,7 @@ func (c *CCIPTestEnv) ChaosLabelForCLNodes(t *testing.T) { for i := c.commitNodeStartIndex; i < len(c.CLNodes); i++ { labelSelector := map[string]string{ "app": "chainlink-0", - "instance": strconv.Itoa(i), + "instance": fmt.Sprintf("node-%d", i), } // commit node starts from index 2 if i >= c.commitNodeStartIndex && i < c.commitNodeStartIndex+c.numOfCommitNodes { diff --git a/integration-tests/ccip-tests/contracts/contract_deployer.go b/integration-tests/ccip-tests/contracts/contract_deployer.go index b60372f4ee..3f8f837846 100644 --- a/integration-tests/ccip-tests/contracts/contract_deployer.go +++ b/integration-tests/ccip-tests/contracts/contract_deployer.go @@ -505,7 +505,31 @@ func (e *CCIPContractsDeployer) DeployWrappedNative() (*common.Address, error) { return address, err } -func DefaultOffChainAggregatorV2Config(numberNodes int) contracts.OffChainAggregatorV2Config { +var OCR2ParamsForCommit = contracts.OffChainAggregatorV2Config{ + DeltaProgress: 2 * time.Minute, + DeltaResend: 5 * time.Second, + DeltaRound: 75 * time.Second, + DeltaGrace: 5 * time.Second, + MaxDurationQuery: 100 * time.Millisecond, + MaxDurationObservation: 35 * time.Second, + MaxDurationReport: 10 * time.Second, + MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, + MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, +} + +var OCR2ParamsForExec = contracts.OffChainAggregatorV2Config{ + DeltaProgress: 100 * time.Second, + DeltaResend: 5 * time.Second, + DeltaRound: 40 * time.Second, + DeltaGrace: 5 * time.Second, + MaxDurationQuery: 100 * time.Millisecond, + MaxDurationObservation: 20 * time.Second, + MaxDurationReport: 8 * time.Second, + MaxDurationShouldAcceptFinalizedReport: 5 * time.Second, + MaxDurationShouldTransmitAcceptedReport: 8 * time.Second, +} + +func OffChainAggregatorV2ConfigWithNodes(numberNodes int, inflightExpiry time.Duration, cfg contracts.OffChainAggregatorV2Config) contracts.OffChainAggregatorV2Config { if numberNodes <= 4 { log.Err(fmt.Errorf("insufficient number of nodes (%d) supplied for OCR, need at least 5", numberNodes)). Int("Number Chainlink Nodes", numberNodes). @@ -523,20 +547,20 @@ func DefaultOffChainAggregatorV2Config(numberNodes int) contracts.OffChainAggreg faultyNodes = 1 } return contracts.OffChainAggregatorV2Config{ - DeltaProgress: 70 * time.Second, - DeltaResend: 5 * time.Second, - DeltaRound: 30 * time.Second, - DeltaGrace: 2 * time.Second, - DeltaStage: 40 * time.Second, + DeltaProgress: cfg.DeltaProgress, + DeltaResend: cfg.DeltaResend, + DeltaRound: cfg.DeltaRound, + DeltaGrace: cfg.DeltaGrace, + DeltaStage: inflightExpiry, RMax: 3, S: s, F: faultyNodes, Oracles: []ocrConfigHelper2.OracleIdentityExtra{}, - MaxDurationQuery: 5 * time.Second, - MaxDurationObservation: 32 * time.Second, - MaxDurationReport: 20 * time.Second, - MaxDurationShouldAcceptFinalizedReport: 10 * time.Second, - MaxDurationShouldTransmitAcceptedReport: 10 * time.Second, + MaxDurationQuery: cfg.MaxDurationQuery, + MaxDurationObservation: cfg.MaxDurationObservation, + MaxDurationReport: cfg.MaxDurationReport, + MaxDurationShouldAcceptFinalizedReport: cfg.MaxDurationShouldAcceptFinalizedReport, + MaxDurationShouldTransmitAcceptedReport: cfg.MaxDurationShouldTransmitAcceptedReport, OnchainConfig: []byte{}, } } @@ -549,10 +573,12 @@ func stripKeyPrefix(key string) string { return key } -func NewOffChainAggregatorV2Config[T ccipconfig.OffchainConfig]( +func NewOffChainAggregatorV2ConfigForCCIPPlugin[T ccipconfig.OffchainConfig]( nodes []*client.CLNodesWithKeys, offchainCfg T, onchainCfg abihelpers.AbiDefined, + ocr2Params contracts.OffChainAggregatorV2Config, + inflightExpiry time.Duration, ) ( signers []common.Address, transmitters []common.Address, @@ -563,7 +589,7 @@ func NewOffChainAggregatorV2Config[T ccipconfig.OffchainConfig]( err error, ) { oracleIdentities := make([]ocrConfigHelper2.OracleIdentityExtra, 0) - ocrConfig := DefaultOffChainAggregatorV2Config(len(nodes)) + ocrConfig := OffChainAggregatorV2ConfigWithNodes(len(nodes), inflightExpiry, ocr2Params) var onChainKeys []ocrtypes2.OnchainPublicKey for i, nodeWithKeys := range nodes { ocr2Key := nodeWithKeys.KeysBundle.OCR2Key.Data diff --git a/integration-tests/ccip-tests/contracts/contract_models.go b/integration-tests/ccip-tests/contracts/contract_models.go index ca26b2f3e3..9191dd142d 100644 --- a/integration-tests/ccip-tests/contracts/contract_models.go +++ b/integration-tests/ccip-tests/contracts/contract_models.go @@ -520,7 +520,11 @@ func (r *Router) CCIPSend(destChainSelector uint64, msg router.ClientEVM2AnyMess opts.Value = valueForNative } - tx, err := r.Instance.CcipSend(opts, destChainSelector, msg) + return r.Instance.CcipSend(opts, destChainSelector, msg) +} + +func (r *Router) CCIPSendAndProcessTx(destChainSelector uint64, msg router.ClientEVM2AnyMessage, valueForNative *big.Int) (*types.Transaction, error) { + tx, err := r.CCIPSend(destChainSelector, msg, valueForNative) if err != nil { return nil, err } diff --git a/integration-tests/ccip-tests/load-test.env b/integration-tests/ccip-tests/load-test.env new file mode 100644 index 0000000000..157c7d7413 --- /dev/null +++ b/integration-tests/ccip-tests/load-test.env @@ -0,0 +1,53 @@ +# This file is used to set the environment variables for the ccip load test. + +export DATABASE_URL="postgresql://postgres:node@localhost:5432/chainlink_test?sslmode=disable" + +# if CCIP_DEPLOY_ON_LOCAL is set to false, the env will be deployed on k8s cluster, otherwise it will be deployed on local docker. +export CCIP_DEPLOY_ON_LOCAL=False +# the test will create new environment with new contracts, chainlink nodes and jobs if CCIP_TESTS_ON_EXISTING_DEPLOYMENT is set to false. +# otherwise, it will use the existing environment. It will assume that deployment has already been completed and +# will ensure the ccip-send and receive is working with the provided contracts under `./integration-tests/ccip-tests/contracts/laneconfig/contracts.json` +export CCIP_TESTS_ON_EXISTING_DEPLOYMENT=False + +# the test will use simulated networks +export SELECTED_NETWORKS="SIMULATED,SIMULATED_1,SIMULATED_2" +export CCIP_NETWORK_PAIRS="" +# th +export CCIP_NO_OF_NETWORKS=10 +export CCIP_NO_OF_LANES_PER_PAIR=2 + +# The load will be triggered as per +# for . Example for following: 1 request per 10s for 1h +export CCIP_LOAD_TEST_RATEUNIT=10s +export CCIP_LOAD_TEST_RATE=1 +export CCIP_TEST_DURATION=1h + +# if CCIP_KEEP_ENV_ALIVE is set to true, the env will not be destroyed after the test. +export CCIP_KEEP_ENV_ALIVE=True + +# if CCIP_CHAINLINK_NODE_FUNDING is set, chainlink nodes will be funded with the mentioned amount in native. +export CCIP_CHAINLINK_NODE_FUNDING=1000 + +# if CCIP_KEEP_ENV_TTL is set, the env will be destroyed after the mentioned duration. +export CCIP_KEEP_ENV_TTL=24h + +# Msg type to use for the load test. Default value is WithToken unless specified. +# Values to choose from WithToken,WithoutToken +export CCIP_MSG_TYPE=WithoutToken + +# remote runner resource requirements +export RR_MEM=16Gi +export RR_CPU=4 + +# pg resource requirements +export CCIP_DB_MEM=6Gi +export CCIP_DB_CPU=2 +export CCIP_DB_ARGS="shared_buffers=1536MB,effective_cache_size=4096MB,work_mem=64MB" + +# node resource requirements +export CCIP_NODE_MEM=4Gi +export CCIP_NODE_CPU=2 + +export DETACH_RUNNER=true +export TEST_SUITE=load +export TEST_ARGS="-test.timeout 900h" diff --git a/integration-tests/ccip-tests/load/ccip_loadgen.go b/integration-tests/ccip-tests/load/ccip_loadgen.go index c254c785ed..37dfd839a6 100644 --- a/integration-tests/ccip-tests/load/ccip_loadgen.go +++ b/integration-tests/ccip-tests/load/ccip_loadgen.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" chain_selectors "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" "go.uber.org/atomic" @@ -126,6 +127,19 @@ func (c *CCIPE2ELoad) BeforeAllCall(msgType string) { sourceCCIP.Common.ChainClient.ParallelTransactions(false) destCCIP.Common.ChainClient.ParallelTransactions(false) + // close all header subscriptions for dest chains + queuedEvents := destCCIP.Common.ChainClient.GetHeaderSubscriptions() + for subName := range queuedEvents { + destCCIP.Common.ChainClient.DeleteHeaderEventSubscription(subName) + } + // close all header subscriptions for source chains except for finalized header + queuedEvents = sourceCCIP.Common.ChainClient.GetHeaderSubscriptions() + for subName := range queuedEvents { + if subName == blockchain.FinalizedHeaderKey { + continue + } + sourceCCIP.Common.ChainClient.DeleteHeaderEventSubscription(subName) + } } func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.CallResult { @@ -135,7 +149,8 @@ func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.CallResult { c.CurrentMsgSerialNo.Inc() lggr := c.Lane.Logger.With().Int("msg Number", int(msgSerialNo)).Logger() - + stats := testreporters.NewCCIPRequestStats(msgSerialNo) + defer c.reports.UpdatePhaseStatsForReq(stats) // form the message for transfer msgStr := fmt.Sprintf("new message with Id %d", msgSerialNo) @@ -188,36 +203,39 @@ func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.CallResult { } if err != nil { - c.reports.UpdatePhaseStats(msgSerialNo, 0, testreporters.TX, time.Since(startTime), testreporters.Failure) + stats.UpdateState(lggr, 0, testreporters.TX, time.Since(startTime), testreporters.Failure) res.Error = fmt.Sprintf("ccip-send tx error %+v for msg ID %d", err, msgSerialNo) - res.Data = c.reports.GetPhaseStatsForRequest(msgSerialNo) + res.Data = stats.StatusByPhase res.Failed = true return res } lggr = lggr.With().Str("Msg Tx", sendTx.Hash().String()).Logger() txConfirmationTime := time.Now().UTC() - rcpt, err1 := c.Lane.Source.Common.ChainClient.GetTxReceipt(sendTx.Hash()) + rcpt, err1 := bind.WaitMined(context.Background(), sourceCCIP.Common.ChainClient.DeployBackend(), sendTx) if err1 == nil { hdr, err1 := c.Lane.Source.Common.ChainClient.HeaderByNumber(context.Background(), rcpt.BlockNumber) if err1 == nil { txConfirmationTime = hdr.Timestamp } } - c.reports.UpdatePhaseStats(msgSerialNo, 0, testreporters.TX, startTime.Sub(txConfirmationTime), testreporters.Success, + var gasUsed uint64 + if rcpt != nil { + gasUsed = rcpt.GasUsed + } + stats.UpdateState(lggr, 0, testreporters.TX, startTime.Sub(txConfirmationTime), testreporters.Success, testreporters.TransactionStats{ Fee: fee.String(), - GasUsed: rcpt.GasUsed, + GasUsed: gasUsed, TxHash: sendTx.Hash().Hex(), NoOfTokensSent: len(msg.TokenAmounts), MessageBytesLength: len(msg.Data), }) // wait for // - CCIPSendRequested Event log to be generated, - msgLog, sourceLogTime, err := c.Lane.Source.AssertEventCCIPSendRequested( - lggr, msgSerialNo, sendTx.Hash().Hex(), c.CallTimeOut, txConfirmationTime, c.reports) + msgLog, sourceLogTime, err := c.Lane.Source.AssertEventCCIPSendRequested(lggr, sendTx.Hash().Hex(), c.CallTimeOut, txConfirmationTime, stats) if err != nil || msgLog == nil { res.Error = err.Error() - res.Data = c.reports.GetPhaseStatsForRequest(msgSerialNo) + res.Data = stats.StatusByPhase res.Failed = true return res } @@ -227,7 +245,7 @@ func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.CallResult { if bytes.Compare(sentMsg.Data, []byte(msgStr)) != 0 { res.Error = fmt.Sprintf("the message byte didnot match expected %s received %s msg ID %d", msgStr, string(sentMsg.Data), msgSerialNo) - res.Data = c.reports.GetPhaseStatsForRequest(msgSerialNo) + res.Data = stats.StatusByPhase res.Failed = true return res } @@ -239,7 +257,7 @@ func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.CallResult { if c.Lane.Source.Common.ChainClient.GetNetworkConfig().FinalityDepth == 0 && lstFinalizedBlock != 0 && lstFinalizedBlock > msgLog.Raw.BlockNumber { sourceLogFinalizedAt = c.LastFinalizedTimestamp.Load() - c.reports.UpdatePhaseStats(msgSerialNo, seqNum, testreporters.SourceLogFinalized, + stats.UpdateState(lggr, seqNum, testreporters.SourceLogFinalized, sourceLogFinalizedAt.Sub(sourceLogTime), testreporters.Success, testreporters.TransactionStats{ TxHash: msgLog.Raw.TxHash.String(), @@ -249,10 +267,10 @@ func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.CallResult { } else { var finalizingBlock uint64 sourceLogFinalizedAt, finalizingBlock, err = c.Lane.Source.AssertSendRequestedLogFinalized( - lggr, msgSerialNo, seqNum, msgLog, sourceLogTime, c.reports) + lggr, seqNum, msgLog, sourceLogTime, stats) if err != nil { res.Error = err.Error() - res.Data = c.reports.GetPhaseStatsForRequest(msgSerialNo) + res.Data = stats.StatusByPhase res.Failed = true return res } @@ -262,37 +280,37 @@ func (c *CCIPE2ELoad) Call(_ *wasp.Generator) *wasp.CallResult { // wait for // - CommitStore to increase the seq number, - err = c.Lane.Dest.AssertSeqNumberExecuted(lggr, msgSerialNo, seqNum, c.CallTimeOut, sourceLogFinalizedAt, c.reports) + err = c.Lane.Dest.AssertSeqNumberExecuted(lggr, seqNum, c.CallTimeOut, sourceLogFinalizedAt, stats) if err != nil { res.Error = err.Error() - res.Data = c.reports.GetPhaseStatsForRequest(msgSerialNo) + res.Data = stats.StatusByPhase res.Failed = true return res } // wait for ReportAccepted event - commitReport, reportAcceptedAt, err := c.Lane.Dest.AssertEventReportAccepted(lggr, msgSerialNo, seqNum, c.CallTimeOut, sourceLogFinalizedAt, c.reports) + commitReport, reportAcceptedAt, err := c.Lane.Dest.AssertEventReportAccepted(lggr, seqNum, c.CallTimeOut, sourceLogFinalizedAt, stats) if err != nil || commitReport == nil { res.Error = err.Error() - res.Data = c.reports.GetPhaseStatsForRequest(msgSerialNo) + res.Data = stats.StatusByPhase res.Failed = true return res } - blessedAt, err := c.Lane.Dest.AssertReportBlessed(lggr, msgSerialNo, seqNum, c.CallTimeOut, *commitReport, reportAcceptedAt, c.reports) + blessedAt, err := c.Lane.Dest.AssertReportBlessed(lggr, seqNum, c.CallTimeOut, *commitReport, reportAcceptedAt, stats) if err != nil { res.Error = err.Error() - res.Data = c.reports.GetPhaseStatsForRequest(msgSerialNo) + res.Data = stats.StatusByPhase res.Failed = true return res } - err = c.Lane.Dest.AssertEventExecutionStateChanged(lggr, msgSerialNo, seqNum, c.CallTimeOut, blessedAt, c.reports) + err = c.Lane.Dest.AssertEventExecutionStateChanged(lggr, seqNum, c.CallTimeOut, blessedAt, stats) if err != nil { res.Error = err.Error() - res.Data = c.reports.GetPhaseStatsForRequest(msgSerialNo) + res.Data = stats.StatusByPhase res.Failed = true return res } - res.Data = c.reports.GetPhaseStatsForRequest(msgSerialNo) + res.Data = stats.StatusByPhase return res } diff --git a/integration-tests/ccip-tests/load/ccip_test.go b/integration-tests/ccip-tests/load/ccip_test.go index 40dfa9d18e..44b8c47fad 100644 --- a/integration-tests/ccip-tests/load/ccip_test.go +++ b/integration-tests/ccip-tests/load/ccip_test.go @@ -18,7 +18,7 @@ func TestLoadCCIPStableRPS(t *testing.T) { t.Parallel() lggr := logging.GetTestLogger(t) testArgs := NewLoadArgs(t, lggr, context.Background()) - testArgs.Setup(true) + testArgs.Setup(true, 5, 5) // if the test runs on remote runner if len(testArgs.TestSetupArgs.Lanes) == 0 { return @@ -40,7 +40,7 @@ func TestLoadCCIPSequentialLaneAdd(t *testing.T) { if len(testArgs.TestCfg.NetworkPairs) <= 1 { t.Skip("Skipping the test as there are not enough network pairs to run the test") } - testArgs.Setup(true) + testArgs.Setup(true, 5, 5) // if the test runs on remote runner if len(testArgs.TestSetupArgs.Lanes) == 0 { return @@ -54,6 +54,50 @@ func TestLoadCCIPSequentialLaneAdd(t *testing.T) { testArgs.Wait() } +func TestLoadCCIPStableRequestTriggeringWithNetworkChaos(t *testing.T) { + t.Parallel() + lggr := logging.GetTestLogger(t) + testArgs := NewLoadArgs(t, lggr, context.Background()) + testArgs.Setup(true, 16, 16) + // if the test runs on remote runner + if len(testArgs.TestSetupArgs.Lanes) == 0 { + return + } + t.Cleanup(func() { + log.Info().Msg("Tearing down the environment") + require.NoError(t, testArgs.TestSetupArgs.TearDown()) + }) + testEnv := testArgs.TestSetupArgs.Env + require.NotNil(t, testEnv) + require.NotNil(t, testEnv.K8Env) + + // apply network chaos so that chainlink's RPC calls are affected by some network delay for the duration of the test + var gethNetworksLabels []string + for _, net := range testArgs.TestCfg.SelectedNetworks { + gethNetworksLabels = append(gethNetworksLabels, actions.GethLabel(net.Name)) + } + testEnv.ChaosLabelForAllGeth(t, gethNetworksLabels) + chaosId, err := testEnv.K8Env.Chaos.Run( + chaos.NewNetworkLatency( + testEnv.K8Env.Cfg.Namespace, &chaos.Props{ + FromLabels: &map[string]*string{"geth": a.Str(actions.ChaosGroupCCIPGeth)}, + ToLabels: &map[string]*string{"app": a.Str("chainlink-0")}, + DurationStr: testArgs.TestCfg.TestDuration.String(), + Delay: "300ms", + })) + require.NoError(t, err) + + t.Cleanup(func() { + if chaosId != "" { + require.NoError(t, testEnv.K8Env.Chaos.Stop(chaosId)) + } + }) + + // now trigger the load + testArgs.TriggerLoad() + testArgs.Wait() +} + // This test applies pod chaos to the CL nodes asynchronously and sequentially while the load is running // the pod chaos is applied at a regular interval throughout the test duration func TestLoadCCIPStableRequestTriggeringWithPodChaos(t *testing.T) { @@ -102,7 +146,7 @@ func TestLoadCCIPStableRequestTriggeringWithPodChaos(t *testing.T) { testArgs.TestCfg.Load.TimeUnit = 1 * time.Second testArgs.TestCfg.Load.RequestPerUnitTime = []int64{2} - testArgs.Setup(false) + testArgs.Setup(false, 5, 5) // if the test runs on remote runner if len(testArgs.TestSetupArgs.Lanes) == 0 { return diff --git a/integration-tests/ccip-tests/load/helper.go b/integration-tests/ccip-tests/load/helper.go index 52e848e2d9..883f060081 100644 --- a/integration-tests/ccip-tests/load/helper.go +++ b/integration-tests/ccip-tests/load/helper.go @@ -46,17 +46,17 @@ type loadArgs struct { ChaosExps []ChaosConfig } -func (l *loadArgs) Setup(sameCommitAndExec bool) { +func (l *loadArgs) Setup(sameCommitAndExec bool, noOfcommit, noOfExec int) { transferAmounts := []*big.Int{big.NewInt(1)} lggr := l.lggr var setUpArgs *testsetups.CCIPTestSetUpOutputs if !l.TestCfg.ExistingDeployment { - replicas := int64(6) + replicas := noOfcommit + 1 if !sameCommitAndExec { - replicas = 12 + replicas = noOfcommit + noOfExec + 2 } setUpArgs = testsetups.CCIPDefaultTestSetUp(l.TestCfg.Test, lggr, "load-ccip", - replicas, transferAmounts, nil, 5, sameCommitAndExec, true, l.TestCfg) + replicas, transferAmounts, nil, noOfcommit, sameCommitAndExec, true, l.TestCfg) } else { setUpArgs = testsetups.CCIPExistingDeploymentTestSetUp(l.TestCfg.Test, lggr, transferAmounts, true, l.TestCfg) } @@ -201,11 +201,12 @@ func (l *loadArgs) Start() { Schedule: l.schedules, LoadType: wasp.RPS, RateLimitUnitDuration: l.TestCfg.Load.TimeUnit, + CallResultBufLen: 10, // we keep the last 10 call results for each generator, as the detailed report is generated at the end of the test CallTimeout: l.TestCfg.Load.LoadTimeOut, Gun: ccipLoad, Logger: ccipLoad.Lane.Logger, SharedData: l.TestCfg.MsgType, - //LokiConfig: wasp.NewEnvLokiConfig(), + LokiConfig: wasp.NewEnvLokiConfig(), Labels: map[string]string{ "test_group": "load", "cluster": "sdlc", diff --git a/integration-tests/ccip-tests/testreporters/ccip.go b/integration-tests/ccip-tests/testreporters/ccip.go index b08c4b2749..e6c5391e19 100644 --- a/integration-tests/ccip-tests/testreporters/ccip.go +++ b/integration-tests/ccip-tests/testreporters/ccip.go @@ -57,78 +57,74 @@ type PhaseStat struct { SendTransactionStats TransactionStats `json:"ccip_send_data,omitempty"` } -type CCIPLaneStats struct { - lane string - lggr zerolog.Logger - TotalRequests int64 `json:"total_requests,omitempty"` // TotalRequests is the total number of requests made - SuccessCountsByPhase map[Phase]int64 `json:"success_counts_by_phase,omitempty"` // SuccessCountsByPhase is the number of requests that succeeded in each phase - FailedCountsByPhase map[Phase]int64 `json:"failed_counts_by_phase,omitempty"` // FailedCountsByPhase is the number of requests that failed in each phase - DurationStatByPhase map[Phase]AggregatorMetrics `json:"duration_stat_by_phase,omitempty"` // DurationStatByPhase is the duration statistics for each phase - StatusByPhaseByRequests map[int64]map[Phase]PhaseStat `json:"status_by_phase_by_requests,omitempty"` // StatusByPhaseByRequests is the status of each phase for each request - mu *sync.Mutex +type RequestStat struct { + reqNo int64 + StatusByPhase map[Phase]PhaseStat `json:"status_by_phase,omitempty"` } -func (testStats *CCIPLaneStats) GetPhaseStatsForRequest(reqNo int64) map[Phase]PhaseStat { - testStats.mu.Lock() - defer testStats.mu.Unlock() - return testStats.StatusByPhaseByRequests[reqNo] -} - -func (testStats *CCIPLaneStats) UpdatePhaseStats(reqNo int64, seqNum uint64, step Phase, duration time.Duration, state Status, sendTransactionStats ...TransactionStats) { - testStats.mu.Lock() - defer testStats.mu.Unlock() +func (stat *RequestStat) UpdateState(lggr zerolog.Logger, seqNum uint64, step Phase, duration time.Duration, state Status, sendTransactionStats ...TransactionStats) { durationInSec := duration.Seconds() - if _, ok := testStats.StatusByPhaseByRequests[reqNo]; !ok { - testStats.StatusByPhaseByRequests[reqNo] = make(map[Phase]PhaseStat) - } - - stat := PhaseStat{ + phaseDetails := PhaseStat{ SeqNum: seqNum, Duration: durationInSec, Status: state, } if len(sendTransactionStats) > 0 { - stat.SendTransactionStats = sendTransactionStats[0] + phaseDetails.SendTransactionStats = sendTransactionStats[0] } - - testStats.StatusByPhaseByRequests[reqNo][step] = stat - event := testStats.lggr.Info() + stat.StatusByPhase[step] = phaseDetails + event := lggr.Info() if seqNum != 0 { event.Uint64("seq num", seqNum) } // if any of the phase fails mark the E2E as failed if state == Failure { - testStats.StatusByPhaseByRequests[reqNo][E2E] = PhaseStat{ + stat.StatusByPhase[E2E] = PhaseStat{ SeqNum: seqNum, Status: state, } - testStats.FailedCountsByPhase[E2E]++ - testStats.FailedCountsByPhase[step]++ - testStats.lggr.Info(). + lggr.Info(). Str(fmt.Sprint(E2E), fmt.Sprintf("%s", Failure)). - Msgf("reqNo %d", reqNo) - event.Str(fmt.Sprint(step), fmt.Sprintf("%s", Failure)).Msgf("reqNo %d", reqNo) + Msgf("reqNo %d", stat.reqNo) + event.Str(fmt.Sprint(step), fmt.Sprintf("%s", Failure)).Msgf("reqNo %d", stat.reqNo) } else { - event.Str(fmt.Sprint(step), fmt.Sprintf("%s", Success)).Msgf("reqNo %d", reqNo) - testStats.SuccessCountsByPhase[step]++ - testStats.Aggregate(step, durationInSec) + event.Str(fmt.Sprint(step), fmt.Sprintf("%s", Success)).Msgf("reqNo %d", stat.reqNo) if step == Commit || step == ReportBlessed || step == ExecStateChanged { - testStats.StatusByPhaseByRequests[reqNo][E2E] = PhaseStat{ + stat.StatusByPhase[E2E] = PhaseStat{ SeqNum: seqNum, Status: state, - Duration: testStats.StatusByPhaseByRequests[reqNo][step].Duration + testStats.StatusByPhaseByRequests[reqNo][E2E].Duration, + Duration: stat.StatusByPhase[step].Duration + stat.StatusByPhase[E2E].Duration, } if step == ExecStateChanged { - testStats.lggr.Info(). + lggr.Info(). Str(fmt.Sprint(E2E), fmt.Sprintf("%s", Success)). - Msgf("reqNo %d", reqNo) - testStats.SuccessCountsByPhase[E2E]++ - testStats.Aggregate(E2E, testStats.StatusByPhaseByRequests[reqNo][E2E].Duration) + Msgf("reqNo %d", stat.reqNo) } } } } +func NewCCIPRequestStats(reqNo int64) *RequestStat { + return &RequestStat{ + reqNo: reqNo, + StatusByPhase: make(map[Phase]PhaseStat), + } +} + +type CCIPLaneStats struct { + lane string + lggr zerolog.Logger + TotalRequests int64 `json:"total_requests,omitempty"` // TotalRequests is the total number of requests made + SuccessCountsByPhase map[Phase]int64 `json:"success_counts_by_phase,omitempty"` // SuccessCountsByPhase is the number of requests that succeeded in each phase + FailedCountsByPhase map[Phase]int64 `json:"failed_counts_by_phase,omitempty"` // FailedCountsByPhase is the number of requests that failed in each phase + DurationStatByPhase map[Phase]AggregatorMetrics `json:"duration_stat_by_phase,omitempty"` // DurationStatByPhase is the duration statistics for each phase + statusByPhaseByRequests sync.Map `json:"-"` +} + +func (testStats *CCIPLaneStats) UpdatePhaseStatsForReq(stat *RequestStat) { + testStats.statusByPhaseByRequests.Store(stat.reqNo, stat.StatusByPhase) +} + func (testStats *CCIPLaneStats) Aggregate(phase Phase, durationInSec float64) { if prevDur, ok := testStats.DurationStatByPhase[phase]; !ok { testStats.DurationStatByPhase[phase] = AggregatorMetrics{ @@ -151,15 +147,28 @@ func (testStats *CCIPLaneStats) Aggregate(phase Phase, durationInSec float64) { } func (testStats *CCIPLaneStats) Finalize(lane string) { - testStats.mu.Lock() - defer testStats.mu.Unlock() phases := []Phase{E2E, TX, CCIPSendRe, SourceLogFinalized, Commit, ReportBlessed, ExecStateChanged} events := make(map[Phase]*zerolog.Event) - for reqNo := range testStats.StatusByPhaseByRequests { - if reqNo > testStats.TotalRequests { - testStats.TotalRequests = reqNo + testStats.statusByPhaseByRequests.Range(func(key, value interface{}) bool { + if reqNo, ok := key.(int64); ok { + if stat, ok := value.(map[Phase]PhaseStat); ok { + for phase, phaseStat := range stat { + if phaseStat.Status == Success { + testStats.SuccessCountsByPhase[phase]++ + testStats.Aggregate(phase, phaseStat.Duration) + } else { + testStats.FailedCountsByPhase[phase]++ + testStats.FailedCountsByPhase[E2E]++ + } + } + } + if reqNo > testStats.TotalRequests { + testStats.TotalRequests = reqNo + } } - } + return true + }) + testStats.lggr.Info().Int64("Total Requests Triggerred", testStats.TotalRequests).Msg("Test Run Completed") for _, phase := range phases { events[phase] = testStats.lggr.Info().Str("Phase", string(phase)) @@ -315,13 +324,11 @@ func (r *CCIPTestReporter) AddNewLane(name string, lggr zerolog.Logger) *CCIPLan r.mu.Lock() defer r.mu.Unlock() i := &CCIPLaneStats{ - lane: name, - lggr: lggr, - FailedCountsByPhase: make(map[Phase]int64), - SuccessCountsByPhase: make(map[Phase]int64), - DurationStatByPhase: make(map[Phase]AggregatorMetrics), - StatusByPhaseByRequests: make(map[int64]map[Phase]PhaseStat), - mu: &sync.Mutex{}, + lane: name, + lggr: lggr, + FailedCountsByPhase: make(map[Phase]int64), + SuccessCountsByPhase: make(map[Phase]int64), + DurationStatByPhase: make(map[Phase]AggregatorMetrics), } r.LaneStats[name] = i return i diff --git a/integration-tests/ccip-tests/testsetups/ccip.go b/integration-tests/ccip-tests/testsetups/ccip.go index 5ffc1933d7..aedee2f67d 100644 --- a/integration-tests/ccip-tests/testsetups/ccip.go +++ b/integration-tests/ccip-tests/testsetups/ccip.go @@ -14,6 +14,7 @@ import ( "github.com/pkg/errors" "github.com/rs/zerolog" + chainselectors "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-env/client" "github.com/smartcontractkit/chainlink-env/environment" "github.com/smartcontractkit/chainlink-env/pkg/helm/chainlink" @@ -34,6 +35,7 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/types/config/node" ccipnode "github.com/smartcontractkit/chainlink/integration-tests/ccip-tests/types/config/node" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + integrationnodes "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" ) const ( @@ -62,15 +64,19 @@ var ( } DONResourceProfile = map[string]interface{}{ "requests": map[string]interface{}{ - "cpu": "4", - "memory": "8Gi", + "cpu": "2", + "memory": "4Gi", }, "limits": map[string]interface{}{ - "cpu": "4", - "memory": "8Gi", + "cpu": "2", + "memory": "4Gi", }, } DONDBResourceProfile = map[string]interface{}{ + "image": map[string]interface{}{ + "image": "postgres", + "version": "13.12", + }, "stateful": true, "capacity": "10Gi", "resources": map[string]interface{}{ @@ -314,8 +320,15 @@ func (p *CCIPTestConfig) SetNetworkPairs(lggr zerolog.Logger) error { if simulated { actualNoOfNetworks := len(p.SelectedNetworks) n := p.SelectedNetworks[0] + var chainIDs []int64 + for _, id := range chainselectors.TestChainIds() { + if id == 2337 { + continue + } + chainIDs = append(chainIDs, int64(id)) + } for i := 0; i < p.NoOfNetworks-actualNoOfNetworks; i++ { - chainID := networks.AdditionalSimulatedChainIds[i] + chainID := chainIDs[i] p.SelectedNetworks = append(p.SelectedNetworks, blockchain.EVMNetwork{ Name: fmt.Sprintf("simulated-non-dev%d", len(p.SelectedNetworks)+1), ChainID: chainID, @@ -324,8 +337,9 @@ func (p *CCIPTestConfig) SetNetworkPairs(lggr zerolog.Logger) error { ChainlinkTransactionLimit: n.ChainlinkTransactionLimit, Timeout: n.Timeout, MinimumConfirmations: n.MinimumConfirmations, - GasEstimationBuffer: n.GasEstimationBuffer, + GasEstimationBuffer: n.GasEstimationBuffer + 1000, ClientImplementation: n.ClientImplementation, + DefaultGasLimit: n.DefaultGasLimit, }) } } @@ -353,9 +367,61 @@ func (p *CCIPTestConfig) FormNetworkPairCombinations() { } } +func SetResourceProfile(defaultcpu, defaultmem, cpu, mem string) map[string]interface{} { + if cpu == "" { + cpu = defaultcpu + } + if mem == "" { + mem = defaultmem + } + return map[string]interface{}{ + "requests": map[string]interface{}{ + "cpu": cpu, + "memory": mem, + }, + "limits": map[string]interface{}{ + "cpu": cpu, + "memory": mem, + }, + } +} + // NewCCIPTestConfig collects all test related CCIPTestConfig from environment variables func NewCCIPTestConfig(t *testing.T, lggr zerolog.Logger, tType string) *CCIPTestConfig { var allError error + nodeMem, _ := utils.GetEnv("CCIP_NODE_MEM") + nodeCPU, _ := utils.GetEnv("CCIP_NODE_CPU") + DONResourceProfile["resources"] = SetResourceProfile("2", "4Gi", nodeCPU, nodeMem) + + dbMem, _ := utils.GetEnv("CCIP_DB_MEM") + dbCPU, _ := utils.GetEnv("CCIP_DB_CPU") + DONDBResourceProfile["resources"] = SetResourceProfile("2", "4Gi", dbCPU, dbMem) + + dbArgs, _ := utils.GetEnv("CCIP_DB_ARGS") + if dbArgs != "" { + args := strings.Split(dbArgs, ",") + var formattedArgs []string + for _, arg := range args { + formattedArgs = append(formattedArgs, "-c") + formattedArgs = append(formattedArgs, arg) + } + DONDBResourceProfile["additionalArgs"] = formattedArgs + } + + ccipTOML, _ := utils.GetEnv("CCIP_TOML_PATH") + if ccipTOML != "" { + tomlFile, err := os.Open(ccipTOML) + if err != nil { + allError = multierr.Append(allError, err) + } else { + defer tomlFile.Close() + _, err := tomlFile.Read(node.CCIPTOML) + if err != nil { + allError = multierr.Append(allError, err) + } + } + } + p := &CCIPTestConfig{ Test: t, MsgType: actions.TokenTransfer, @@ -852,7 +918,7 @@ func CCIPDefaultTestSetUp( t *testing.T, lggr zerolog.Logger, envName string, - numOfCLNodes int64, + numOfCLNodes int, transferAmounts []*big.Int, tokenDeployerFns []blockchain.ContractDeployer, numOfCommitNodes int, commitAndExecOnSameDON, bidirectional bool, @@ -907,7 +973,7 @@ func CCIPDefaultTestSetUp( } } else { clProps := make(map[string]interface{}) - clProps["replicas"] = strconv.FormatInt(numOfCLNodes, 10) + clProps["replicas"] = numOfCLNodes clProps["db"] = inputs.CLNodeDBResourceProfile clProps["chainlink"] = map[string]interface{}{ "resources": inputs.CLNodeResourceProfile, @@ -965,13 +1031,13 @@ func CCIPDefaultTestSetUp( chainByChainID[n.ChainID] = ec } } - - t.Cleanup(func() { - if inputs.KeepEnvAlive { - return + printStats := func() { + for k := range setUpArgs.Reporter.LaneStats { + setUpArgs.Reporter.LaneStats[k].Finalize(k) } + } + t.Cleanup(func() { if configureCLNode { - lggr.Info().Msg("Tearing down the environment") if ccipEnv.LocalCluster != nil { err := ccipEnv.LocalCluster.Terminate() require.NoError(t, err, "Local cluster termination shouldn't fail") @@ -980,14 +1046,17 @@ func CCIPDefaultTestSetUp( } return } + if inputs.KeepEnvAlive { + printStats() + return + } + lggr.Info().Msg("Tearing down the environment") err = integrationactions.TeardownSuite(t, ccipEnv.K8Env, utils.ProjectRoot, ccipEnv.CLNodes, setUpArgs.Reporter, zapcore.ErrorLevel, chains...) require.NoError(t, err, "Environment teardown shouldn't fail") } else { //just print - for k := range setUpArgs.Reporter.LaneStats { - setUpArgs.Reporter.LaneStats[k].Finalize(k) - } + printStats() } }) @@ -1125,7 +1194,7 @@ func CCIPExistingDeploymentTestSetUp( func DeployLocalCluster( t *testing.T, - noOfCLNodes int64, + noOfCLNodes int, networks []blockchain.EVMNetwork, ) (*test_env.CLClusterTestEnv, func() error) { env, err := test_env.NewCLTestEnvBuilder(). @@ -1142,15 +1211,16 @@ func DeployLocalCluster( } } } - + configOpts := []integrationnodes.NodeConfigOpt{ + node.WithPrivateEVMs(networks), + } // a func to start the CL nodes asynchronously deployCL := func() error { - toml, err := node.NewConfigFromToml(ccipnode.CCIPTOML, - node.WithPrivateEVMs(networks)) + toml, err := node.NewConfigFromToml(ccipnode.CCIPTOML, configOpts...) if err != nil { return err } - return env.StartClNodes(toml, int(noOfCLNodes)) + return env.StartClNodes(toml, noOfCLNodes, "") } return env, deployCL } @@ -1234,7 +1304,10 @@ func DeployEnvironments( */ } - tomlCfg, err := node.NewConfigFromToml(ccipnode.CCIPTOML, ccipnode.WithPrivateEVMs(nets)) + tomlCfg, err := node.NewConfigFromToml( + ccipnode.CCIPTOML, + ccipnode.WithPrivateEVMs(nets), + ) tomlStr, err := tomlCfg.TOMLString() require.NoError(t, err) clProps["toml"] = tomlStr diff --git a/integration-tests/chaos/automation_chaos_test.go b/integration-tests/chaos/automation_chaos_test.go index 1b18b9f6ab..c292c130c5 100644 --- a/integration-tests/chaos/automation_chaos_test.go +++ b/integration-tests/chaos/automation_chaos_test.go @@ -42,7 +42,7 @@ AnnounceAddresses = ["0.0.0.0:6690"] ListenAddresses = ["0.0.0.0:6690"]` defaultAutomationSettings = map[string]interface{}{ - "replicas": "6", + "replicas": 6, "toml": client.AddNetworksConfig(baseTOML, networks.SelectedNetwork), "db": map[string]interface{}{ "stateful": true, @@ -194,11 +194,11 @@ func TestAutomationChaos(t *testing.T) { return } - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 1, 2, ChaosGroupMinority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=node-", 1, 2, ChaosGroupMinority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 3, 5, ChaosGroupMajority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=node-", 3, 5, ChaosGroupMajority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 2, 5, ChaosGroupMajorityPlus) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=node-", 2, 5, ChaosGroupMajorityPlus) require.NoError(t, err) chainClient, err := blockchain.NewEVMClient(network, testEnvironment, l) diff --git a/integration-tests/chaos/ocr2vrf_chaos_test.go b/integration-tests/chaos/ocr2vrf_chaos_test.go index fd51fa55db..1d7f61f783 100644 --- a/integration-tests/chaos/ocr2vrf_chaos_test.go +++ b/integration-tests/chaos/ocr2vrf_chaos_test.go @@ -34,7 +34,7 @@ func TestOCR2VRFChaos(t *testing.T) { loadedNetwork := networks.SelectedNetwork defaultOCR2VRFSettings := map[string]interface{}{ - "replicas": "6", + "replicas": 6, "toml": client.AddNetworkDetailedConfig( config.BaseOCR2Config, config.DefaultOCR2VRFNetworkDetailTomlConfig, @@ -135,9 +135,9 @@ func TestOCR2VRFChaos(t *testing.T) { return } - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 1, 2, ChaosGroupMinority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=node-", 1, 2, ChaosGroupMinority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 3, 5, ChaosGroupMajority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=node-", 3, 5, ChaosGroupMajority) require.NoError(t, err) chainClient, err := blockchain.NewEVMClient(testNetwork, testEnvironment, l) diff --git a/integration-tests/chaos/ocr_chaos_test.go b/integration-tests/chaos/ocr_chaos_test.go index 569a0d1b70..f3ee12046f 100644 --- a/integration-tests/chaos/ocr_chaos_test.go +++ b/integration-tests/chaos/ocr_chaos_test.go @@ -32,7 +32,7 @@ import ( var ( defaultOCRSettings = map[string]interface{}{ - "replicas": "6", + "replicas": 6, "db": map[string]interface{}{ "stateful": true, "capacity": "1Gi", @@ -146,11 +146,11 @@ func TestOCRChaos(t *testing.T) { return } - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 1, 2, ChaosGroupMinority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=node-", 1, 2, ChaosGroupMinority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 3, 5, ChaosGroupMajority) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=node-", 3, 5, ChaosGroupMajority) require.NoError(t, err) - err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=", 2, 5, ChaosGroupMajorityPlus) + err = testEnvironment.Client.LabelChaosGroup(testEnvironment.Cfg.Namespace, "instance=node-", 2, 5, ChaosGroupMajorityPlus) require.NoError(t, err) chainClient, err := blockchain.NewEVMClient(blockchain.SimulatedEVMNetwork, testEnvironment, l) diff --git a/integration-tests/contracts/contract_deployer.go b/integration-tests/contracts/contract_deployer.go index 1242d3dc94..e92b3870fa 100644 --- a/integration-tests/contracts/contract_deployer.go +++ b/integration-tests/contracts/contract_deployer.go @@ -51,6 +51,11 @@ 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" + "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/gethwrappers/shared/generated/werc20_mock" ) // ContractDeployer is an interface for abstracting the contract deployment methods across network implementations @@ -60,6 +65,7 @@ type ContractDeployer interface { DeployFlags(rac string) (Flags, error) DeployFluxAggregatorContract(linkAddr string, fluxOptions FluxAggregatorOptions) (FluxAggregator, error) DeployLinkTokenContract() (LinkToken, error) + DeployWERC20Mock() (WERC20Mock, error) LoadLinkToken(address common.Address) (LinkToken, error) DeployOffChainAggregator(linkAddr string, offchainOptions OffchainOptions) (OffchainAggregator, error) LoadOffChainAggregator(address *common.Address) (OffchainAggregator, error) @@ -91,10 +97,12 @@ type ContractDeployer interface { DeployVRFv2Consumer(coordinatorAddr string) (VRFv2Consumer, error) DeployVRFv2LoadTestConsumer(coordinatorAddr string) (VRFv2LoadTestConsumer, error) DeployVRFv2PlusLoadTestConsumer(coordinatorAddr string) (VRFv2PlusLoadTestConsumer, error) + DeployVRFV2PlusWrapperLoadTestConsumer(linkAddr string, vrfV2PlusWrapperAddr string) (VRFv2PlusWrapperLoadTestConsumer, error) DeployVRFCoordinator(linkAddr string, bhsAddr string) (VRFCoordinator, error) DeployVRFCoordinatorV2(linkAddr string, bhsAddr string, linkEthFeedAddr string) (VRFCoordinatorV2, error) - DeployVRFCoordinatorV2Plus(bhsAddr string) (VRFCoordinatorV2Plus, error) + DeployVRFCoordinatorV2_5(bhsAddr string) (VRFCoordinatorV2_5, error) DeployVRFCoordinatorV2PlusUpgradedVersion(bhsAddr string) (VRFCoordinatorV2PlusUpgradedVersion, error) + DeployVRFV2PlusWrapper(linkAddr string, linkEthFeedAddr string, coordinatorAddr string) (VRFV2PlusWrapper, error) DeployDKG() (DKG, error) DeployOCR2VRFCoordinator(beaconPeriodBlocksCount *big.Int, linkAddr string) (VRFCoordinatorV3, error) DeployVRFBeacon(vrfCoordinatorAddress string, linkAddress string, dkgAddress string, keyId string) (VRFBeacon, error) @@ -115,6 +123,10 @@ type ContractDeployer interface { DeployKeeperRegistry11Mock() (KeeperRegistry11Mock, error) DeployKeeperRegistrar12Mock() (KeeperRegistrar12Mock, error) DeployKeeperGasWrapperMock() (KeeperGasWrapperMock, error) + DeployMercuryVerifierContract(verifierProxyAddr common.Address) (MercuryVerifier, error) + DeployMercuryVerifierProxyContract(accessControllerAddr common.Address) (MercuryVerifierProxy, error) + DeployMercuryFeeManager(linkAddress common.Address, nativeAddress common.Address, proxyAddress common.Address, rewardManagerAddress common.Address) (MercuryFeeManager, error) + DeployMercuryRewardManager(linkAddress common.Address) (MercuryRewardManager, error) } // NewContractDeployer returns an instance of a contract deployer based on the client type @@ -1434,3 +1446,93 @@ func (e *EthereumContractDeployer) DeployOffchainAggregatorV2( l: e.l, }, err } + +func (e *EthereumContractDeployer) DeployMercuryVerifierContract(verifierProxyAddr common.Address) (MercuryVerifier, error) { + address, _, instance, err := e.client.DeployContract("Mercury Verifier", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return verifier.DeployVerifier(auth, backend, verifierProxyAddr) + }) + if err != nil { + return nil, err + } + return &EthereumMercuryVerifier{ + client: e.client, + instance: instance.(*verifier.Verifier), + address: *address, + l: e.l, + }, err +} + +func (e *EthereumContractDeployer) DeployMercuryVerifierProxyContract(accessControllerAddr common.Address) (MercuryVerifierProxy, error) { + address, _, instance, err := e.client.DeployContract("Mercury Verifier Proxy", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return verifier_proxy.DeployVerifierProxy(auth, backend, accessControllerAddr) + }) + if err != nil { + return nil, err + } + return &EthereumMercuryVerifierProxy{ + client: e.client, + instance: instance.(*verifier_proxy.VerifierProxy), + address: *address, + l: e.l, + }, err +} + +func (e *EthereumContractDeployer) DeployMercuryFeeManager(linkAddress common.Address, nativeAddress common.Address, proxyAddress common.Address, rewardManagerAddress common.Address) (MercuryFeeManager, error) { + address, _, instance, err := e.client.DeployContract("Mercury Fee Manager", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return fee_manager.DeployFeeManager(auth, backend, linkAddress, nativeAddress, proxyAddress, rewardManagerAddress) + }) + if err != nil { + return nil, err + } + return &EthereumMercuryFeeManager{ + client: e.client, + instance: instance.(*fee_manager.FeeManager), + address: *address, + l: e.l, + }, err +} + +func (e *EthereumContractDeployer) DeployMercuryRewardManager(linkAddress common.Address) (MercuryRewardManager, error) { + address, _, instance, err := e.client.DeployContract("Mercury Reward Manager", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return reward_manager.DeployRewardManager(auth, backend, linkAddress) + }) + if err != nil { + return nil, err + } + return &EthereumMercuryRewardManager{ + client: e.client, + instance: instance.(*reward_manager.RewardManager), + address: *address, + l: e.l, + }, err +} + +func (e *EthereumContractDeployer) DeployWERC20Mock() (WERC20Mock, error) { + address, _, instance, err := e.client.DeployContract("WERC20 Mock", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return werc20_mock.DeployWERC20Mock(auth, backend) + }) + if err != nil { + return nil, err + } + return &EthereumWERC20Mock{ + client: e.client, + instance: instance.(*werc20_mock.WERC20Mock), + address: *address, + l: e.l, + }, err +} diff --git a/integration-tests/contracts/contract_loader.go b/integration-tests/contracts/contract_loader.go index a790747e38..fc0272b107 100644 --- a/integration-tests/contracts/contract_loader.go +++ b/integration-tests/contracts/contract_loader.go @@ -14,8 +14,11 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/authorized_forwarder" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/link_token_interface" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/operator_wrapper" + "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/gethwrappers/shared/generated/werc20_mock" ) // ContractLoader is an interface for abstracting the contract loading methods across network implementations @@ -30,8 +33,12 @@ type ContractLoader interface { LoadFunctionsLoadTestClient(addr string) (FunctionsLoadTestClient, error) // Mercury - LoadMercuryVerifier(addr string) (MercuryVerifier, error) - LoadMercuryVerifierProxy(addr string) (MercuryVerifierProxy, error) + LoadMercuryVerifier(addr common.Address) (MercuryVerifier, error) + LoadMercuryVerifierProxy(addr common.Address) (MercuryVerifierProxy, error) + LoadMercuryFeeManager(addr common.Address) (MercuryFeeManager, error) + LoadMercuryRewardManager(addr common.Address) (MercuryRewardManager, error) + + LoadWERC20Mock(addr common.Address) (WERC20Mock, error) } // NewContractLoader returns an instance of a contract Loader based on the client type @@ -204,8 +211,8 @@ func (e *EthereumContractLoader) LoadAuthorizedForwarder(address common.Address) } // LoadMercuryVerifier returns Verifier contract deployed on given address -func (e *EthereumContractLoader) LoadMercuryVerifier(addr string) (MercuryVerifier, error) { - instance, err := e.client.LoadContract("Mercury Verifier", common.HexToAddress(addr), func( +func (e *EthereumContractLoader) LoadMercuryVerifier(addr common.Address) (MercuryVerifier, error) { + instance, err := e.client.LoadContract("Mercury Verifier", addr, func( address common.Address, backend bind.ContractBackend, ) (interface{}, error) { @@ -217,13 +224,13 @@ func (e *EthereumContractLoader) LoadMercuryVerifier(addr string) (MercuryVerifi return &EthereumMercuryVerifier{ client: e.client, instance: instance.(*verifier.Verifier), - address: common.HexToAddress(addr), + address: addr, }, err } // LoadMercuryVerifierProxy returns VerifierProxy contract deployed on given address -func (e *EthereumContractLoader) LoadMercuryVerifierProxy(addr string) (MercuryVerifierProxy, error) { - instance, err := e.client.LoadContract("Mercury Verifier Proxy", common.HexToAddress(addr), func( +func (e *EthereumContractLoader) LoadMercuryVerifierProxy(addr common.Address) (MercuryVerifierProxy, error) { + instance, err := e.client.LoadContract("Mercury Verifier Proxy", addr, func( address common.Address, backend bind.ContractBackend, ) (interface{}, error) { @@ -235,6 +242,57 @@ func (e *EthereumContractLoader) LoadMercuryVerifierProxy(addr string) (MercuryV return &EthereumMercuryVerifierProxy{ client: e.client, instance: instance.(*verifier_proxy.VerifierProxy), - address: common.HexToAddress(addr), + address: addr, + }, err +} + +func (e *EthereumContractLoader) LoadMercuryFeeManager(addr common.Address) (MercuryFeeManager, error) { + instance, err := e.client.LoadContract("Mercury Fee Manager", addr, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return fee_manager.NewFeeManager(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumMercuryFeeManager{ + client: e.client, + instance: instance.(*fee_manager.FeeManager), + address: addr, + }, err +} + +func (e *EthereumContractLoader) LoadMercuryRewardManager(addr common.Address) (MercuryRewardManager, error) { + instance, err := e.client.LoadContract("Mercury Reward Manager", addr, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return reward_manager.NewRewardManager(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumMercuryRewardManager{ + client: e.client, + instance: instance.(*reward_manager.RewardManager), + address: addr, + }, err +} + +func (e *EthereumContractLoader) LoadWERC20Mock(addr common.Address) (WERC20Mock, error) { + instance, err := e.client.LoadContract("WERC20 Mock", addr, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return werc20_mock.NewWERC20Mock(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumWERC20Mock{ + client: e.client, + instance: instance.(*werc20_mock.WERC20Mock), + address: addr, }, err } diff --git a/integration-tests/contracts/contract_models.go b/integration-tests/contracts/contract_models.go index 9f1130dce9..51fce7cb12 100644 --- a/integration-tests/contracts/contract_models.go +++ b/integration-tests/contracts/contract_models.go @@ -17,6 +17,7 @@ import ( "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/v2/core/gethwrappers/llo-feeds/generated/verifier" ) type FluxAggregatorOptions struct { @@ -369,12 +370,33 @@ type FunctionsLoadTestClient interface { } type MercuryVerifier interface { - Address() string + Address() common.Address Verify(signedReport []byte, sender common.Address) error + SetConfig(feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []verifier.CommonAddressAndWeight) (*types.Transaction, error) + LatestConfigDetails(ctx context.Context, feedId [32]byte) (verifier.LatestConfigDetails, error) } type MercuryVerifierProxy interface { - Address() string + Address() common.Address + InitializeVerifier(verifierAddress common.Address) (*types.Transaction, error) Verify(signedReport []byte, parameterPayload []byte, value *big.Int) (*types.Transaction, error) VerifyBulk(signedReports [][]byte, parameterPayload []byte, value *big.Int) (*types.Transaction, error) + SetFeeManager(feeManager common.Address) (*types.Transaction, error) +} + +type MercuryFeeManager interface { + Address() common.Address +} + +type MercuryRewardManager interface { + Address() common.Address + SetFeeManager(feeManager common.Address) (*types.Transaction, error) +} + +type WERC20Mock interface { + Address() common.Address + BalanceOf(ctx context.Context, addr string) (*big.Int, error) + Approve(to string, amount *big.Int) error + Transfer(to string, amount *big.Int) error + Mint(account common.Address, amount *big.Int) (*types.Transaction, error) } diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index 491983c8c7..2b623469aa 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -2,12 +2,15 @@ package contracts import ( "context" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" + "math/big" "time" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" @@ -53,10 +56,10 @@ type VRFCoordinatorV2 interface { GetSubscription(ctx context.Context, subID uint64) (vrf_coordinator_v2.GetSubscription, error) } -type VRFCoordinatorV2Plus interface { - SetLINKAndLINKETHFeed( +type VRFCoordinatorV2_5 interface { + SetLINKAndLINKNativeFeed( link string, - linkEthFeed string, + linkNativeFeed string, ) error SetConfig( minimumRequestConfirmations uint16, @@ -64,7 +67,7 @@ type VRFCoordinatorV2Plus interface { stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, - feeConfig vrf_coordinator_v2plus.VRFCoordinatorV2PlusFeeConfig, + feeConfig vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig, ) error RegisterProvingKey( oracleAddr string, @@ -76,21 +79,21 @@ type VRFCoordinatorV2Plus interface { Migrate(subId *big.Int, coordinatorAddress string) error RegisterMigratableCoordinator(migratableCoordinatorAddress string) error AddConsumer(subId *big.Int, consumerAddress string) error - FundSubscriptionWithEth(subId *big.Int, nativeTokenAmount *big.Int) error + FundSubscriptionWithNative(subId *big.Int, nativeTokenAmount *big.Int) error Address() string - GetSubscription(ctx context.Context, subID *big.Int) (vrf_coordinator_v2plus.GetSubscription, error) + GetSubscription(ctx context.Context, subID *big.Int) (vrf_coordinator_v2_5.GetSubscription, error) GetNativeTokenTotalBalance(ctx context.Context) (*big.Int, error) GetLinkTotalBalance(ctx context.Context) (*big.Int, error) FindSubscriptionID() (*big.Int, error) - WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled, error) - WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested, error) - WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_coordinator_v2plus.VRFCoordinatorV2PlusMigrationCompleted, error) + WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) + WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested, error) + WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25MigrationCompleted, error) } type VRFCoordinatorV2PlusUpgradedVersion interface { - SetLINKAndLINKETHFeed( + SetLINKAndLINKNativeFeed( link string, - linkEthFeed string, + linkNativeFeed string, ) error SetConfig( minimumRequestConfirmations uint16, @@ -111,7 +114,7 @@ type VRFCoordinatorV2PlusUpgradedVersion interface { Migrate(subId *big.Int, coordinatorAddress string) error RegisterMigratableCoordinator(migratableCoordinatorAddress string) error AddConsumer(subId *big.Int, consumerAddress string) error - FundSubscriptionWithEth(subId *big.Int, nativeTokenAmount *big.Int) error + FundSubscriptionWithNative(subId *big.Int, nativeTokenAmount *big.Int) error Address() string GetSubscription(ctx context.Context, subID *big.Int) (vrf_v2plus_upgraded_version.GetSubscription, error) GetActiveSubscriptionIds(ctx context.Context, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) @@ -121,6 +124,12 @@ type VRFCoordinatorV2PlusUpgradedVersion interface { WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, error) } +type VRFV2PlusWrapper interface { + Address() string + SetConfig(wrapperGasOverhead uint32, coordinatorGasOverhead uint32, wrapperPremiumPercentage uint8, keyHash [32]byte, maxNumWords uint8, stalenessSeconds uint32, fallbackWeiPerUnitLink *big.Int, fulfillmentFlatFeeLinkPPM uint32, fulfillmentFlatFeeNativePPM uint32) error + GetSubID(ctx context.Context) (*big.Int, error) +} + type VRFConsumer interface { Address() string RequestRandomness(hash [32]byte, fee *big.Int) error @@ -165,6 +174,17 @@ type VRFv2PlusLoadTestConsumer interface { GetCoordinator(ctx context.Context) (common.Address, error) } +type VRFv2PlusWrapperLoadTestConsumer interface { + Address() string + Fund(ethAmount *big.Float) error + RequestRandomness(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) + RequestRandomnessNative(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) + GetRequestStatus(ctx context.Context, requestID *big.Int) (vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, error) + GetLastRequestId(ctx context.Context) (*big.Int, error) + GetWrapper(ctx context.Context) (common.Address, error) + GetLoadTestMetrics(ctx context.Context) (*VRFLoadTestMetrics, error) +} + type DKG interface { Address() string AddClient(keyID string, clientAddress string) error diff --git a/integration-tests/contracts/ethereum_contracts.go b/integration-tests/contracts/ethereum_contracts.go index d3db6913c5..fdeccfedad 100644 --- a/integration-tests/contracts/ethereum_contracts.go +++ b/integration-tests/contracts/ethereum_contracts.go @@ -47,8 +47,11 @@ 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/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/gethwrappers/shared/generated/werc20_mock" ) // EthereumOracle oracle for "directrequest" job tests @@ -2269,10 +2272,11 @@ type EthereumMercuryVerifier struct { address common.Address client blockchain.EVMClient instance *verifier.Verifier + l zerolog.Logger } -func (e *EthereumMercuryVerifier) Address() string { - return e.address.Hex() +func (e *EthereumMercuryVerifier) Address() common.Address { + return e.address } func (e *EthereumMercuryVerifier) Verify(signedReport []byte, sender common.Address) error { @@ -2287,14 +2291,57 @@ func (e *EthereumMercuryVerifier) Verify(signedReport []byte, sender common.Addr return e.client.ProcessTransaction(tx) } +func (e *EthereumMercuryVerifier) SetConfig(feedId [32]byte, signers []common.Address, offchainTransmitters [][32]byte, f uint8, onchainConfig []byte, offchainConfigVersion uint64, offchainConfig []byte, recipientAddressesAndWeights []verifier.CommonAddressAndWeight) (*types.Transaction, error) { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if err != nil { + return nil, err + } + tx, err := e.instance.SetConfig(opts, feedId, signers, offchainTransmitters, f, onchainConfig, offchainConfigVersion, offchainConfig, recipientAddressesAndWeights) + e.l.Info().Err(err).Str("contractAddress", e.address.Hex()).Hex("feedId", feedId[:]).Msg("Called EthereumMercuryVerifier.SetConfig()") + if err != nil { + return nil, err + } + return tx, e.client.ProcessTransaction(tx) +} + +func (e *EthereumMercuryVerifier) LatestConfigDetails(ctx context.Context, feedId [32]byte) (verifier.LatestConfigDetails, error) { + opts := &bind.CallOpts{ + From: common.HexToAddress(e.client.GetDefaultWallet().Address()), + Context: ctx, + } + d, err := e.instance.LatestConfigDetails(opts, feedId) + e.l.Info().Err(err).Str("contractAddress", e.address.Hex()).Hex("feedId", feedId[:]). + Interface("details", d). + Msg("Called EthereumMercuryVerifier.LatestConfigDetails()") + if err != nil { + return verifier.LatestConfigDetails{}, err + } + return d, nil +} + type EthereumMercuryVerifierProxy struct { address common.Address client blockchain.EVMClient instance *verifier_proxy.VerifierProxy + l zerolog.Logger } -func (e *EthereumMercuryVerifierProxy) Address() string { - return e.address.Hex() +func (e *EthereumMercuryVerifierProxy) Address() common.Address { + return e.address +} + +func (e *EthereumMercuryVerifierProxy) InitializeVerifier(verifierAddress common.Address) (*types.Transaction, error) { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if err != nil { + return nil, err + } + tx, err := e.instance.InitializeVerifier(opts, verifierAddress) + e.l.Info().Err(err).Str("contractAddress", e.address.Hex()).Str("verifierAddress", verifierAddress.Hex()). + Msg("Called EthereumMercuryVerifierProxy.InitializeVerifier()") + if err != nil { + return nil, err + } + return tx, e.client.ProcessTransaction(tx) } func (e *EthereumMercuryVerifierProxy) Verify(signedReport []byte, parameterPayload []byte, value *big.Int) (*types.Transaction, error) { @@ -2305,7 +2352,7 @@ func (e *EthereumMercuryVerifierProxy) Verify(signedReport []byte, parameterPayl if err != nil { return nil, err } - tx, err := e.instance.Verify(opts, parameterPayload, signedReport) + tx, err := e.instance.Verify(opts, signedReport, parameterPayload) if err != nil { return nil, err } @@ -2326,3 +2373,126 @@ func (e *EthereumMercuryVerifierProxy) VerifyBulk(signedReports [][]byte, parame } return tx, e.client.ProcessTransaction(tx) } + +func (e *EthereumMercuryVerifierProxy) SetFeeManager(feeManager common.Address) (*types.Transaction, error) { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if err != nil { + return nil, err + } + tx, err := e.instance.SetFeeManager(opts, feeManager) + e.l.Info().Err(err).Str("feeManager", feeManager.Hex()).Msg("Called MercuryVerifierProxy.SetFeeManager()") + if err != nil { + return nil, err + } + return tx, e.client.ProcessTransaction(tx) +} + +type EthereumMercuryFeeManager struct { + address common.Address + client blockchain.EVMClient + instance *fee_manager.FeeManager + l zerolog.Logger +} + +func (e *EthereumMercuryFeeManager) Address() common.Address { + return e.address +} + +type EthereumMercuryRewardManager struct { + address common.Address + client blockchain.EVMClient + instance *reward_manager.RewardManager + l zerolog.Logger +} + +func (e *EthereumMercuryRewardManager) Address() common.Address { + return e.address +} + +func (e *EthereumMercuryRewardManager) SetFeeManager(feeManager common.Address) (*types.Transaction, error) { + opts, err := e.client.TransactionOpts(e.client.GetDefaultWallet()) + if err != nil { + return nil, err + } + tx, err := e.instance.SetFeeManager(opts, feeManager) + e.l.Info().Err(err).Str("feeManager", feeManager.Hex()).Msg("Called EthereumMercuryRewardManager.SetFeeManager()") + if err != nil { + return nil, err + } + return tx, e.client.ProcessTransaction(tx) +} + +type EthereumWERC20Mock struct { + address common.Address + client blockchain.EVMClient + instance *werc20_mock.WERC20Mock + l zerolog.Logger +} + +func (e *EthereumWERC20Mock) Address() common.Address { + return e.address +} + +func (l *EthereumWERC20Mock) Approve(to string, amount *big.Int) error { + opts, err := l.client.TransactionOpts(l.client.GetDefaultWallet()) + if err != nil { + return err + } + l.l.Info(). + Str("From", l.client.GetDefaultWallet().Address()). + Str("To", to). + Str("Amount", amount.String()). + Uint64("Nonce", opts.Nonce.Uint64()). + Msg("Approving LINK Transfer") + tx, err := l.instance.Approve(opts, common.HexToAddress(to), amount) + if err != nil { + return err + } + return l.client.ProcessTransaction(tx) +} + +func (l *EthereumWERC20Mock) BalanceOf(ctx context.Context, addr string) (*big.Int, error) { + opts := &bind.CallOpts{ + From: common.HexToAddress(l.client.GetDefaultWallet().Address()), + Context: ctx, + } + balance, err := l.instance.BalanceOf(opts, common.HexToAddress(addr)) + if err != nil { + return nil, err + } + return balance, nil +} + +func (l *EthereumWERC20Mock) Transfer(to string, amount *big.Int) error { + opts, err := l.client.TransactionOpts(l.client.GetDefaultWallet()) + if err != nil { + return err + } + l.l.Info(). + Str("From", l.client.GetDefaultWallet().Address()). + Str("To", to). + Str("Amount", amount.String()). + Uint64("Nonce", opts.Nonce.Uint64()). + Msg("EthereumWERC20Mock.Transfer()") + tx, err := l.instance.Transfer(opts, common.HexToAddress(to), amount) + if err != nil { + return err + } + return l.client.ProcessTransaction(tx) +} + +func (l *EthereumWERC20Mock) Mint(account common.Address, amount *big.Int) (*types.Transaction, error) { + opts, err := l.client.TransactionOpts(l.client.GetDefaultWallet()) + if err != nil { + return nil, err + } + l.l.Info(). + Str("account", account.Hex()). + Str("amount", amount.String()). + Msg("EthereumWERC20Mock.Mint()") + tx, err := l.instance.Mint(opts, account, amount) + if err != nil { + return tx, err + } + return tx, l.client.ProcessTransaction(tx) +} diff --git a/integration-tests/contracts/ethereum_vrfv2_contracts.go b/integration-tests/contracts/ethereum_vrfv2_contracts.go index ca3ad64d7b..88dfe58eb2 100644 --- a/integration-tests/contracts/ethereum_vrfv2_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2_contracts.go @@ -13,7 +13,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_consumer_v2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_load_test_with_metrics" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" "math/big" ) @@ -116,23 +115,6 @@ func (e *EthereumContractDeployer) DeployVRFv2LoadTestConsumer(coordinatorAddr s }, err } -func (e *EthereumContractDeployer) DeployVRFv2PlusLoadTestConsumer(coordinatorAddr string) (VRFv2PlusLoadTestConsumer, error) { - address, _, instance, err := e.client.DeployContract("VRFV2PlusLoadTestWithMetrics", func( - auth *bind.TransactOpts, - backend bind.ContractBackend, - ) (common.Address, *types.Transaction, interface{}, error) { - return vrf_v2plus_load_test_with_metrics.DeployVRFV2PlusLoadTestWithMetrics(auth, backend, common.HexToAddress(coordinatorAddr)) - }) - if err != nil { - return nil, err - } - return &EthereumVRFv2PlusLoadTestConsumer{ - client: e.client, - consumer: instance.(*vrf_v2plus_load_test_with_metrics.VRFV2PlusLoadTestWithMetrics), - address: address, - }, err -} - func (v *EthereumVRFCoordinatorV2) Address() string { return v.address.Hex() } diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index 565cdaed4e..4ca5c0fec4 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -3,21 +3,25 @@ package contracts import ( "context" "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/smartcontractkit/chainlink-testing-framework/blockchain" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2plus" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" - "math/big" - "time" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" ) -type EthereumVRFCoordinatorV2Plus struct { +type EthereumVRFCoordinatorV2_5 struct { address *common.Address client blockchain.EVMClient - coordinator *vrf_coordinator_v2plus.VRFCoordinatorV2Plus + coordinator vrf_coordinator_v2_5.VRFCoordinatorV25Interface } type EthereumVRFCoordinatorV2PlusUpgradedVersion struct { @@ -33,29 +37,41 @@ type EthereumVRFv2PlusLoadTestConsumer struct { consumer *vrf_v2plus_load_test_with_metrics.VRFV2PlusLoadTestWithMetrics } -// DeployVRFCoordinatorV2Plus deploys VRFV2Plus coordinator contract -func (e *EthereumContractDeployer) DeployVRFCoordinatorV2Plus(bhsAddr string) (VRFCoordinatorV2Plus, error) { +type EthereumVRFV2PlusWrapperLoadTestConsumer struct { + address *common.Address + client blockchain.EVMClient + consumer *vrfv2plus_wrapper_load_test_consumer.VRFV2PlusWrapperLoadTestConsumer +} + +type EthereumVRFV2PlusWrapper struct { + address *common.Address + client blockchain.EVMClient + wrapper *vrfv2plus_wrapper.VRFV2PlusWrapper +} + +// DeployVRFCoordinatorV2_5 deploys VRFV2_5 coordinator contract +func (e *EthereumContractDeployer) DeployVRFCoordinatorV2_5(bhsAddr string) (VRFCoordinatorV2_5, error) { address, _, instance, err := e.client.DeployContract("VRFCoordinatorV2Plus", func( auth *bind.TransactOpts, backend bind.ContractBackend, ) (common.Address, *types.Transaction, interface{}, error) { - return vrf_coordinator_v2plus.DeployVRFCoordinatorV2Plus(auth, backend, common.HexToAddress(bhsAddr)) + return vrf_coordinator_v2_5.DeployVRFCoordinatorV25(auth, backend, common.HexToAddress(bhsAddr)) }) if err != nil { return nil, err } - return &EthereumVRFCoordinatorV2Plus{ + return &EthereumVRFCoordinatorV2_5{ client: e.client, - coordinator: instance.(*vrf_coordinator_v2plus.VRFCoordinatorV2Plus), + coordinator: instance.(*vrf_coordinator_v2_5.VRFCoordinatorV25), address: address, }, err } -func (v *EthereumVRFCoordinatorV2Plus) Address() string { +func (v *EthereumVRFCoordinatorV2_5) Address() string { return v.address.Hex() } -func (v *EthereumVRFCoordinatorV2Plus) HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error) { +func (v *EthereumVRFCoordinatorV2_5) HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error) { opts := &bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, @@ -67,7 +83,7 @@ func (v *EthereumVRFCoordinatorV2Plus) HashOfKey(ctx context.Context, pubKey [2] return hash, nil } -func (v *EthereumVRFCoordinatorV2Plus) GetActiveSubscriptionIds(ctx context.Context, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { +func (v *EthereumVRFCoordinatorV2_5) GetActiveSubscriptionIds(ctx context.Context, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) { opts := &bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, @@ -79,19 +95,19 @@ func (v *EthereumVRFCoordinatorV2Plus) GetActiveSubscriptionIds(ctx context.Cont return activeSubscriptionIds, nil } -func (v *EthereumVRFCoordinatorV2Plus) GetSubscription(ctx context.Context, subID *big.Int) (vrf_coordinator_v2plus.GetSubscription, error) { +func (v *EthereumVRFCoordinatorV2_5) GetSubscription(ctx context.Context, subID *big.Int) (vrf_coordinator_v2_5.GetSubscription, error) { opts := &bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, } subscription, err := v.coordinator.GetSubscription(opts, subID) if err != nil { - return vrf_coordinator_v2plus.GetSubscription{}, err + return vrf_coordinator_v2_5.GetSubscription{}, err } return subscription, nil } -func (v *EthereumVRFCoordinatorV2Plus) GetLinkTotalBalance(ctx context.Context) (*big.Int, error) { +func (v *EthereumVRFCoordinatorV2_5) GetLinkTotalBalance(ctx context.Context) (*big.Int, error) { opts := &bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, @@ -102,19 +118,19 @@ func (v *EthereumVRFCoordinatorV2Plus) GetLinkTotalBalance(ctx context.Context) } return totalBalance, nil } -func (v *EthereumVRFCoordinatorV2Plus) GetNativeTokenTotalBalance(ctx context.Context) (*big.Int, error) { +func (v *EthereumVRFCoordinatorV2_5) GetNativeTokenTotalBalance(ctx context.Context) (*big.Int, error) { opts := &bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, } - totalBalance, err := v.coordinator.STotalEthBalance(opts) + totalBalance, err := v.coordinator.STotalNativeBalance(opts) if err != nil { return nil, err } return totalBalance, nil } -func (v *EthereumVRFCoordinatorV2Plus) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig vrf_coordinator_v2plus.VRFCoordinatorV2PlusFeeConfig) error { +func (v *EthereumVRFCoordinatorV2_5) SetConfig(minimumRequestConfirmations uint16, maxGasLimit uint32, stalenessSeconds uint32, gasAfterPaymentCalculation uint32, fallbackWeiPerUnitLink *big.Int, feeConfig vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err @@ -134,15 +150,15 @@ func (v *EthereumVRFCoordinatorV2Plus) SetConfig(minimumRequestConfirmations uin return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2Plus) SetLINKAndLINKETHFeed(linkAddress string, linkEthFeedAddress string) error { +func (v *EthereumVRFCoordinatorV2_5) SetLINKAndLINKNativeFeed(linkAddress string, linkNativeFeedAddress string) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err } - tx, err := v.coordinator.SetLINKAndLINKETHFeed( + tx, err := v.coordinator.SetLINKAndLINKNativeFeed( opts, common.HexToAddress(linkAddress), - common.HexToAddress(linkEthFeedAddress), + common.HexToAddress(linkNativeFeedAddress), ) if err != nil { return err @@ -150,7 +166,7 @@ func (v *EthereumVRFCoordinatorV2Plus) SetLINKAndLINKETHFeed(linkAddress string, return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2Plus) RegisterProvingKey( +func (v *EthereumVRFCoordinatorV2_5) RegisterProvingKey( oracleAddr string, publicProvingKey [2]*big.Int, ) error { @@ -165,7 +181,7 @@ func (v *EthereumVRFCoordinatorV2Plus) RegisterProvingKey( return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2Plus) CreateSubscription() error { +func (v *EthereumVRFCoordinatorV2_5) CreateSubscription() error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err @@ -177,7 +193,7 @@ func (v *EthereumVRFCoordinatorV2Plus) CreateSubscription() error { return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2Plus) Migrate(subId *big.Int, coordinatorAddress string) error { +func (v *EthereumVRFCoordinatorV2_5) Migrate(subId *big.Int, coordinatorAddress string) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err @@ -189,7 +205,7 @@ func (v *EthereumVRFCoordinatorV2Plus) Migrate(subId *big.Int, coordinatorAddres return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2Plus) RegisterMigratableCoordinator(migratableCoordinatorAddress string) error { +func (v *EthereumVRFCoordinatorV2_5) RegisterMigratableCoordinator(migratableCoordinatorAddress string) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err @@ -201,7 +217,7 @@ func (v *EthereumVRFCoordinatorV2Plus) RegisterMigratableCoordinator(migratableC return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2Plus) AddConsumer(subId *big.Int, consumerAddress string) error { +func (v *EthereumVRFCoordinatorV2_5) AddConsumer(subId *big.Int, consumerAddress string) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err @@ -217,13 +233,13 @@ func (v *EthereumVRFCoordinatorV2Plus) AddConsumer(subId *big.Int, consumerAddre return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2Plus) FundSubscriptionWithEth(subId *big.Int, nativeTokenAmount *big.Int) error { +func (v *EthereumVRFCoordinatorV2_5) FundSubscriptionWithNative(subId *big.Int, nativeTokenAmount *big.Int) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err } opts.Value = nativeTokenAmount - tx, err := v.coordinator.FundSubscriptionWithEth( + tx, err := v.coordinator.FundSubscriptionWithNative( opts, subId, ) @@ -233,7 +249,7 @@ func (v *EthereumVRFCoordinatorV2Plus) FundSubscriptionWithEth(subId *big.Int, n return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2Plus) FindSubscriptionID() (*big.Int, error) { +func (v *EthereumVRFCoordinatorV2_5) FindSubscriptionID() (*big.Int, error) { owner := v.client.GetDefaultWallet().Address() subscriptionIterator, err := v.coordinator.FilterSubscriptionCreated( nil, @@ -250,8 +266,8 @@ func (v *EthereumVRFCoordinatorV2Plus) FindSubscriptionID() (*big.Int, error) { return subscriptionIterator.Event.SubId, nil } -func (v *EthereumVRFCoordinatorV2Plus) WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled, error) { - randomWordsFulfilledEventsChannel := make(chan *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsFulfilled) +func (v *EthereumVRFCoordinatorV2_5) WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { + randomWordsFulfilledEventsChannel := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled) subscription, err := v.coordinator.WatchRandomWordsFulfilled(nil, randomWordsFulfilledEventsChannel, requestID, subID) if err != nil { return nil, err @@ -270,8 +286,8 @@ func (v *EthereumVRFCoordinatorV2Plus) WaitForRandomWordsFulfilledEvent(subID [] } } -func (v *EthereumVRFCoordinatorV2Plus) WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested, error) { - randomWordsFulfilledEventsChannel := make(chan *vrf_coordinator_v2plus.VRFCoordinatorV2PlusRandomWordsRequested) +func (v *EthereumVRFCoordinatorV2_5) WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested, error) { + randomWordsFulfilledEventsChannel := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested) subscription, err := v.coordinator.WatchRandomWordsRequested(nil, randomWordsFulfilledEventsChannel, keyHash, subID, sender) if err != nil { return nil, err @@ -283,15 +299,15 @@ func (v *EthereumVRFCoordinatorV2Plus) WaitForRandomWordsRequestedEvent(keyHash case err := <-subscription.Err(): return nil, err case <-time.After(timeout): - return nil, fmt.Errorf("timeout waiting for RandomWordsFulfilled event") + return nil, fmt.Errorf("timeout waiting for RandomWordsRequested event") case randomWordsFulfilledEvent := <-randomWordsFulfilledEventsChannel: return randomWordsFulfilledEvent, nil } } } -func (v *EthereumVRFCoordinatorV2Plus) WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_coordinator_v2plus.VRFCoordinatorV2PlusMigrationCompleted, error) { - eventsChannel := make(chan *vrf_coordinator_v2plus.VRFCoordinatorV2PlusMigrationCompleted) +func (v *EthereumVRFCoordinatorV2_5) WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25MigrationCompleted, error) { + eventsChannel := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25MigrationCompleted) subscription, err := v.coordinator.WatchMigrationCompleted(nil, eventsChannel) if err != nil { return nil, err @@ -471,15 +487,15 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) SetConfig(minimumRequestCo return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) SetLINKAndLINKETHFeed(linkAddress string, linkEthFeedAddress string) error { +func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) SetLINKAndLINKNativeFeed(linkAddress string, linkNativeFeedAddress string) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err } - tx, err := v.coordinator.SetLINKAndLINKETHFeed( + tx, err := v.coordinator.SetLINKAndLINKNativeFeed( opts, common.HexToAddress(linkAddress), - common.HexToAddress(linkEthFeedAddress), + common.HexToAddress(linkNativeFeedAddress), ) if err != nil { return err @@ -530,7 +546,7 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) GetNativeTokenTotalBalance From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, } - totalBalance, err := v.coordinator.STotalEthBalance(opts) + totalBalance, err := v.coordinator.STotalNativeBalance(opts) if err != nil { return nil, err } @@ -577,13 +593,13 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) AddConsumer(subId *big.Int return v.client.ProcessTransaction(tx) } -func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) FundSubscriptionWithEth(subId *big.Int, nativeTokenAmount *big.Int) error { +func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) FundSubscriptionWithNative(subId *big.Int, nativeTokenAmount *big.Int) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err } opts.Value = nativeTokenAmount - tx, err := v.coordinator.FundSubscriptionWithEth( + tx, err := v.coordinator.FundSubscriptionWithNative( opts, subId, ) @@ -669,3 +685,204 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForRandomWordsRequeste } } } + +func (e *EthereumContractDeployer) DeployVRFv2PlusLoadTestConsumer(coordinatorAddr string) (VRFv2PlusLoadTestConsumer, error) { + address, _, instance, err := e.client.DeployContract("VRFV2PlusLoadTestWithMetrics", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return vrf_v2plus_load_test_with_metrics.DeployVRFV2PlusLoadTestWithMetrics(auth, backend, common.HexToAddress(coordinatorAddr)) + }) + if err != nil { + return nil, err + } + return &EthereumVRFv2PlusLoadTestConsumer{ + client: e.client, + consumer: instance.(*vrf_v2plus_load_test_with_metrics.VRFV2PlusLoadTestWithMetrics), + address: address, + }, err +} + +func (e *EthereumContractDeployer) DeployVRFV2PlusWrapper(linkAddr string, linkEthFeedAddr string, coordinatorAddr string) (VRFV2PlusWrapper, error) { + address, _, instance, err := e.client.DeployContract("VRFV2PlusWrapper", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return vrfv2plus_wrapper.DeployVRFV2PlusWrapper(auth, backend, common.HexToAddress(linkAddr), common.HexToAddress(linkEthFeedAddr), common.HexToAddress(coordinatorAddr)) + }) + if err != nil { + return nil, err + } + return &EthereumVRFV2PlusWrapper{ + client: e.client, + wrapper: instance.(*vrfv2plus_wrapper.VRFV2PlusWrapper), + address: address, + }, err +} + +func (v *EthereumVRFV2PlusWrapper) Address() string { + return v.address.Hex() +} + +func (e *EthereumContractDeployer) DeployVRFV2PlusWrapperLoadTestConsumer(linkAddr string, vrfV2PlusWrapperAddr string) (VRFv2PlusWrapperLoadTestConsumer, error) { + address, _, instance, err := e.client.DeployContract("VRFV2PlusWrapperLoadTestConsumer", func( + auth *bind.TransactOpts, + backend bind.ContractBackend, + ) (common.Address, *types.Transaction, interface{}, error) { + return vrfv2plus_wrapper_load_test_consumer.DeployVRFV2PlusWrapperLoadTestConsumer(auth, backend, common.HexToAddress(linkAddr), common.HexToAddress(vrfV2PlusWrapperAddr)) + }) + if err != nil { + return nil, err + } + return &EthereumVRFV2PlusWrapperLoadTestConsumer{ + client: e.client, + consumer: instance.(*vrfv2plus_wrapper_load_test_consumer.VRFV2PlusWrapperLoadTestConsumer), + address: address, + }, err +} + +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) Address() string { + return v.address.Hex() +} + +func (v *EthereumVRFV2PlusWrapper) SetConfig(wrapperGasOverhead uint32, + coordinatorGasOverhead uint32, + wrapperPremiumPercentage uint8, + keyHash [32]byte, + maxNumWords uint8, + stalenessSeconds uint32, + fallbackWeiPerUnitLink *big.Int, + fulfillmentFlatFeeLinkPPM uint32, + fulfillmentFlatFeeNativePPM uint32, +) error { + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := v.wrapper.SetConfig( + opts, + wrapperGasOverhead, + coordinatorGasOverhead, + wrapperPremiumPercentage, + keyHash, + maxNumWords, + stalenessSeconds, + fallbackWeiPerUnitLink, + fulfillmentFlatFeeLinkPPM, + fulfillmentFlatFeeNativePPM, + ) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) +} + +func (v *EthereumVRFV2PlusWrapper) GetSubID(ctx context.Context) (*big.Int, error) { + return v.wrapper.SUBSCRIPTIONID(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) +} + +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) Fund(ethAmount *big.Float) error { + gasEstimates, err := v.client.EstimateGas(ethereum.CallMsg{}) + if err != nil { + return err + } + return v.client.Fund(v.address.Hex(), ethAmount, gasEstimates) +} + +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) RequestRandomness(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) { + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return nil, err + } + tx, err := v.consumer.MakeRequests(opts, callbackGasLimit, requestConfirmations, numWords, requestCount) + if err != nil { + return nil, err + } + + return tx, v.client.ProcessTransaction(tx) +} + +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) RequestRandomnessNative(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) { + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return nil, err + } + tx, err := v.consumer.MakeRequestsNative(opts, callbackGasLimit, requestConfirmations, numWords, requestCount) + if err != nil { + return nil, err + } + + return tx, v.client.ProcessTransaction(tx) +} + +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, error) { + return v.consumer.GetRequestStatus(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }, requestID) +} + +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) GetLastRequestId(ctx context.Context) (*big.Int, error) { + return v.consumer.SLastRequestId(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) +} + +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) GetWrapper(ctx context.Context) (common.Address, error) { + return v.consumer.GetWrapper(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) +} + +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) GetLoadTestMetrics(ctx context.Context) (*VRFLoadTestMetrics, error) { + requestCount, err := v.consumer.SRequestCount(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) + if err != nil { + return nil, err + } + fulfilmentCount, err := v.consumer.SResponseCount(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) + + if err != nil { + return nil, err + } + averageFulfillmentInMillions, err := v.consumer.SAverageFulfillmentInMillions(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) + if err != nil { + return nil, err + } + slowestFulfillment, err := v.consumer.SSlowestFulfillment(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) + + if err != nil { + return nil, err + } + fastestFulfillment, err := v.consumer.SFastestFulfillment(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) + if err != nil { + return nil, err + } + + return &VRFLoadTestMetrics{ + requestCount, + fulfilmentCount, + averageFulfillmentInMillions, + slowestFulfillment, + fastestFulfillment, + }, nil +} diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go index 3045dd4a16..dbf9fdffaa 100644 --- a/integration-tests/docker/test_env/cl_node.go +++ b/integration-tests/docker/test_env/cl_node.go @@ -16,7 +16,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" - "github.com/pelletier/go-toml/v2" + "github.com/pelletier/go-toml" "github.com/pkg/errors" "github.com/rs/zerolog" "github.com/rs/zerolog/log" @@ -59,6 +59,12 @@ type ClNode struct { type ClNodeOption = func(c *ClNode) +func WithSecrets(secretsTOML string) ClNodeOption { + return func(c *ClNode) { + c.NodeSecretsConfigTOML = secretsTOML + } +} + // Sets custom node container name if name is not empty func WithNodeContainerName(name string) ClNodeOption { return func(c *ClNode) { @@ -238,17 +244,20 @@ func (n *ClNode) StartContainer() error { if err != nil { return err } + + // If the node secrets TOML is not set, generate it with the default template nodeSecretsToml, err := templates.NodeSecretsTemplate{ - PgDbName: n.PostgresDb.DbName, - PgHost: n.PostgresDb.ContainerName, - PgPort: n.PostgresDb.Port, - PgPassword: n.PostgresDb.Password, + PgDbName: n.PostgresDb.DbName, + PgHost: n.PostgresDb.ContainerName, + PgPort: n.PostgresDb.Port, + PgPassword: n.PostgresDb.Password, + CustomSecrets: n.NodeSecretsConfigTOML, }.String() if err != nil { return err } - n.NodeSecretsConfigTOML = nodeSecretsToml - cReq, err := n.getContainerRequest() + + cReq, err := n.getContainerRequest(nodeSecretsToml) if err != nil { return err } @@ -303,7 +312,7 @@ func (n *ClNode) StartContainer() error { return nil } -func (n *ClNode) getContainerRequest() ( +func (n *ClNode) getContainerRequest(secrets string) ( *tc.ContainerRequest, error) { configFile, err := os.CreateTemp("", "node_config") if err != nil { @@ -321,7 +330,7 @@ func (n *ClNode) getContainerRequest() ( if err != nil { return nil, err } - _, err = secretsFile.WriteString(n.NodeSecretsConfigTOML) + _, err = secretsFile.WriteString(secrets) if err != nil { return nil, err } diff --git a/integration-tests/docker/test_env/test_env.go b/integration-tests/docker/test_env/test_env.go index 52624cfb6f..acf6d30021 100644 --- a/integration-tests/docker/test_env/test_env.go +++ b/integration-tests/docker/test_env/test_env.go @@ -60,15 +60,25 @@ func NewTestEnv() (*CLClusterTestEnv, error) { if err != nil { return nil, err } - networks := []string{network.Name} + n := []string{network.Name} return &CLClusterTestEnv{ + Geth: test_env.NewGeth(n), + MockServer: test_env.NewMockServer(n), Network: network, - Geth: test_env.NewGeth(networks), - MockServer: test_env.NewMockServer(networks), l: log.Logger, }, nil } +// WithTestEnvConfig sets the test environment cfg. +// Sets up the Geth and MockServer containers with the provided cfg. +func (te *CLClusterTestEnv) WithTestEnvConfig(cfg *TestEnvConfig) *CLClusterTestEnv { + te.Cfg = cfg + n := []string{te.Network.Name} + te.Geth = test_env.NewGeth(n, test_env.WithContainerName(cfg.Geth.ContainerName)) + te.MockServer = test_env.NewMockServer(n, test_env.WithContainerName(cfg.MockServer.ContainerName)) + return te +} + func (te *CLClusterTestEnv) WithTestLogger(t *testing.T) *CLClusterTestEnv { te.t = t te.l = logging.GetTestLogger(t) @@ -77,23 +87,6 @@ func (te *CLClusterTestEnv) WithTestLogger(t *testing.T) *CLClusterTestEnv { return te } -func NewTestEnvFromCfg(l zerolog.Logger, cfg *TestEnvConfig) (*CLClusterTestEnv, error) { - utils.SetupCoreDockerEnvLogger() - network, err := docker.CreateNetwork(log.Logger) - if err != nil { - return nil, err - } - networks := []string{network.Name} - l.Info().Interface("Cfg", cfg).Send() - return &CLClusterTestEnv{ - Cfg: cfg, - Network: network, - Geth: test_env.NewGeth(networks, test_env.WithContainerName(cfg.Geth.ContainerName)), - MockServer: test_env.NewMockServer(networks, test_env.WithContainerName(cfg.MockServer.ContainerName)), - l: log.Logger, - }, nil -} - func (te *CLClusterTestEnv) ParallelTransactions(enabled bool) { te.EVMClient.ParallelTransactions(enabled) } @@ -125,7 +118,7 @@ func (te *CLClusterTestEnv) StartPrivateChain() error { for _, chain := range te.PrivateChain { primaryNode := chain.GetPrimaryNode() if primaryNode == nil { - return errors.WithStack(fmt.Errorf("Primary node is nil in PrivateChain interface")) + return errors.WithStack(fmt.Errorf("primary node is nil in PrivateChain interface")) } err := primaryNode.Start() if err != nil { @@ -156,7 +149,7 @@ func (te *CLClusterTestEnv) GetAPIs() []*client.ChainlinkClient { } // StartClNodes start one bootstrap node and {count} OCR nodes -func (te *CLClusterTestEnv) StartClNodes(nodeConfig *chainlink.Config, count int) error { +func (te *CLClusterTestEnv) StartClNodes(nodeConfig *chainlink.Config, count int, secretsConfig string) error { eg := &errgroup.Group{} nodes := make(chan *ClNode, count) @@ -170,6 +163,7 @@ func (te *CLClusterTestEnv) StartClNodes(nodeConfig *chainlink.Config, count int dbContainerName = te.Cfg.Nodes[nodeIndex].DbContainerName } n := NewClNode([]string{te.Network.Name}, nodeConfig, + WithSecrets(secretsConfig), WithNodeContainerName(nodeContainerName), WithDbContainerName(dbContainerName), ) @@ -248,6 +242,45 @@ func (te *CLClusterTestEnv) Cleanup(t *testing.T) error { return errors.New("chainlink nodes are nil, unable to return funds from chainlink nodes") } + // TODO: This is an imperfect and temporary solution, see TT-590 for a more sustainable solution + // Collect logs if the test fails, or if we just want them + if t.Failed() || os.Getenv("TEST_LOG_COLLECT") == "true" { + folder := fmt.Sprintf("./logs/%s-%s", t.Name(), time.Now().Format("2006-01-02T15-04-05")) + if err := os.MkdirAll(folder, os.ModePerm); err != nil { + return err + } + + te.l.Info().Msg("Collecting test logs") + eg := &errgroup.Group{} + for _, n := range te.CLNodes { + node := n + eg.Go(func() error { + logFileName := filepath.Join(folder, fmt.Sprintf("node-%s.log", node.ContainerName)) + logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return err + } + defer logFile.Close() + logReader, err := node.Container.Logs(context.Background()) + if err != nil { + return err + } + _, err = io.Copy(logFile, logReader) + if err != nil { + return err + } + te.l.Info().Str("Node", node.ContainerName).Str("File", logFileName).Msg("Wrote Logs") + return nil + }) + } + + if err := eg.Wait(); err != nil { + return err + } + + te.l.Info().Str("Logs Location", folder).Msg("Wrote test logs") + } + // Check if we need to return funds if te.EVMClient.NetworkSimulated() { te.l.Info().Str("Network Name", te.EVMClient.GetNetworkName()). @@ -277,46 +310,5 @@ func (te *CLClusterTestEnv) Cleanup(t *testing.T) error { } } - // TODO: This is an imperfect and temporary solution, see TT-590 for a more sustainable solution - // Collect logs if the test failed - if !t.Failed() { - return nil - } - - folder := fmt.Sprintf("./logs/%s-%s", t.Name(), time.Now().Format("2006-01-02T15-04-05")) - if err := os.MkdirAll(folder, os.ModePerm); err != nil { - return err - } - - te.l.Warn().Msg("Test failed, collecting logs") - eg := &errgroup.Group{} - for _, n := range te.CLNodes { - node := n - eg.Go(func() error { - logFileName := filepath.Join(folder, fmt.Sprintf("node-%s.log", node.ContainerName)) - logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return err - } - defer logFile.Close() - logReader, err := node.Container.Logs(context.Background()) - if err != nil { - return err - } - _, err = io.Copy(logFile, logReader) - if err != nil { - return err - } - te.l.Info().Str("Node", node.ContainerName).Str("File", logFileName).Msg("Wrote Logs") - return nil - }) - } - - if err := eg.Wait(); err != nil { - return err - } - - te.l.Info().Str("Logs Location", folder).Msg("Wrote Logs for Failed Test") - return nil } diff --git a/integration-tests/docker/test_env/test_env_builder.go b/integration-tests/docker/test_env/test_env_builder.go index 73dacd10ca..83783fda38 100644 --- a/integration-tests/docker/test_env/test_env_builder.go +++ b/integration-tests/docker/test_env/test_env_builder.go @@ -28,6 +28,7 @@ type CLTestEnvBuilder struct { hasMockServer bool hasForwarders bool clNodeConfig *chainlink.Config + secretsConfig string nonDevGethNetworks []blockchain.EVMNetwork clNodesCount int externalAdapterCount int @@ -35,6 +36,8 @@ type CLTestEnvBuilder struct { defaultNodeCsaKeys []string l zerolog.Logger t *testing.T + te *CLClusterTestEnv + isNonEVM bool /* funding */ ETHFunds *big.Float @@ -47,6 +50,38 @@ func NewCLTestEnvBuilder() *CLTestEnvBuilder { } } +// WithTestEnv sets the test environment to use for the test. +// If nil, a new test environment is created. +// If not nil, the test environment is used as-is. +// If TEST_ENV_CONFIG_PATH is set, the test environment is created with the config at that path. +func (b *CLTestEnvBuilder) WithTestEnv(te *CLClusterTestEnv) (*CLTestEnvBuilder, error) { + envConfigPath, isSet := os.LookupEnv("TEST_ENV_CONFIG_PATH") + var cfg *TestEnvConfig + var err error + if isSet { + cfg, err = NewTestEnvConfigFromFile(envConfigPath) + if err != nil { + return nil, err + } + } + + if te != nil { + b.te = te + } else { + b.te, err = NewTestEnv() + if err != nil { + return nil, err + } + } + + if cfg != nil { + b.te = b.te.WithTestEnvConfig(cfg) + } + return b, nil +} + +// WithTestLogger sets the test logger to use for the test. +// Useful for parallel tests so the logging will be separated correctly in the results views. func (b *CLTestEnvBuilder) WithTestLogger(t *testing.T) *CLTestEnvBuilder { b.t = t b.l = logging.GetTestLogger(t) @@ -88,26 +123,31 @@ func (b *CLTestEnvBuilder) WithCLNodeConfig(cfg *chainlink.Config) *CLTestEnvBui return b } +func (b *CLTestEnvBuilder) WithSecretsConfig(secrets string) *CLTestEnvBuilder { + b.secretsConfig = secrets + return b +} + func (b *CLTestEnvBuilder) WithMockServer(externalAdapterCount int) *CLTestEnvBuilder { b.hasMockServer = true b.externalAdapterCount = externalAdapterCount return b } +// WithNonEVM sets the test environment to not use EVM when built. +func (b *CLTestEnvBuilder) WithNonEVM() *CLTestEnvBuilder { + b.isNonEVM = true + return b +} + func (b *CLTestEnvBuilder) Build() (*CLClusterTestEnv, error) { - envConfigPath, isSet := os.LookupEnv("TEST_ENV_CONFIG_PATH") - if isSet { - cfg, err := NewTestEnvConfigFromFile(envConfigPath) + if b.te == nil { + var err error + b, err = b.WithTestEnv(nil) 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) { b.l.Info(). Bool("hasGeth", b.hasGeth). Bool("hasMockServer", b.hasMockServer). @@ -117,52 +157,39 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e Strs("defaultNodeCsaKeys", b.defaultNodeCsaKeys). Msg("Building CL cluster test environment..") - var te *CLClusterTestEnv var err error - if cfg != nil { - te, err = NewTestEnvFromCfg(b.l, cfg) - if err != nil { - return nil, err - } - } else { - te, err = NewTestEnv() - if err != nil { - return nil, err - } - } - if b.t != nil { - te.WithTestLogger(b.t) + b.te.WithTestLogger(b.t) } if b.hasLogWatch { - te.LogWatch, err = logwatch.NewLogWatch(nil, nil) + b.te.LogWatch, err = logwatch.NewLogWatch(nil, nil) if err != nil { return nil, err } } if b.hasMockServer { - err = te.StartMockServer() + err = b.te.StartMockServer() if err != nil { return nil, err } - err = te.MockServer.SetExternalAdapterMocks(b.externalAdapterCount) + err = b.te.MockServer.SetExternalAdapterMocks(b.externalAdapterCount) if err != nil { return nil, err } } if b.nonDevGethNetworks != nil { - te.WithPrivateChain(b.nonDevGethNetworks) - err := te.StartPrivateChain() + b.te.WithPrivateChain(b.nonDevGethNetworks) + err := b.te.StartPrivateChain() if err != nil { - return te, err + return b.te, err } var nonDevNetworks []blockchain.EVMNetwork - for i, n := range te.PrivateChain { + for i, n := range b.te.PrivateChain { primaryNode := n.GetPrimaryNode() if primaryNode == nil { - return te, errors.WithStack(fmt.Errorf("Primary node is nil in PrivateChain interface")) + return b.te, errors.WithStack(fmt.Errorf("primary node is nil in PrivateChain interface")) } nonDevNetworks = append(nonDevNetworks, *n.GetNetworkConfig()) nonDevNetworks[i].URLs = []string{primaryNode.GetInternalWsUrl()} @@ -172,41 +199,42 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e return nil, errors.New("cannot create nodes with custom config without nonDevNetworks") } if b.clNodesCount > 0 { - err = te.StartClNodes(b.clNodeConfig, b.clNodesCount) + err = b.te.StartClNodes(b.clNodeConfig, b.clNodesCount, b.secretsConfig) if err != nil { return nil, err } } - return te, nil + return b.te, nil } networkConfig := networks.SelectedNetwork var internalDockerUrls test_env.InternalDockerUrls if b.hasGeth && networkConfig.Simulated { - networkConfig, internalDockerUrls, err = te.StartGeth() + networkConfig, internalDockerUrls, err = b.te.StartGeth() if err != nil { return nil, err } } - bc, err := blockchain.NewEVMClientFromNetwork(networkConfig, b.l) - if err != nil { - return nil, err - } - - te.EVMClient = bc + if !b.isNonEVM { + bc, err := blockchain.NewEVMClientFromNetwork(networkConfig, b.l) + if err != nil { + return nil, err + } - cd, err := contracts.NewContractDeployer(bc, b.l) - if err != nil { - return nil, err - } - te.ContractDeployer = cd + b.te.EVMClient = bc + cd, err := contracts.NewContractDeployer(bc, b.l) + if err != nil { + return nil, err + } + b.te.ContractDeployer = cd - cl, err := contracts.NewContractLoader(bc, b.l) - if err != nil { - return nil, err + cl, err := contracts.NewContractLoader(bc, b.l) + if err != nil { + return nil, err + } + b.te.ContractLoader = cl } - te.ContractLoader = cl var nodeCsaKeys []string @@ -221,26 +249,27 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e 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 - } + if !b.isNonEVM { + 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) + node.SetChainConfig(cfg, wsUrls, httpUrls, networkConfig, b.hasForwarders) + } - err := te.StartClNodes(cfg, b.clNodesCount) + err := b.te.StartClNodes(cfg, b.clNodesCount, b.secretsConfig) if err != nil { return nil, err } - nodeCsaKeys, err = te.GetNodeCSAKeys() + nodeCsaKeys, err = b.te.GetNodeCSAKeys() if err != nil { return nil, err } @@ -248,12 +277,12 @@ func (b *CLTestEnvBuilder) buildNewEnv(cfg *TestEnvConfig) (*CLClusterTestEnv, e } if b.hasGeth && b.clNodesCount > 0 && b.ETHFunds != nil { - te.ParallelTransactions(true) - defer te.ParallelTransactions(false) - if err := te.FundChainlinkNodes(b.ETHFunds); err != nil { + b.te.ParallelTransactions(true) + defer b.te.ParallelTransactions(false) + if err := b.te.FundChainlinkNodes(b.ETHFunds); err != nil { return nil, err } } - return te, nil + return b.te, nil } diff --git a/integration-tests/example.env b/integration-tests/example.env index 428f76b914..3e27ac2c7a 100644 --- a/integration-tests/example.env +++ b/integration-tests/example.env @@ -2,11 +2,11 @@ # `source ./integration-tests/.env` ########## General Test Settings ########## -export KEEP_ENVIRONMENTS="Never" # Always | OnFail | Never export CHAINLINK_IMAGE="public.ecr.aws/chainlink/chainlink" # Image repo to pull the Chainlink image from export CHAINLINK_VERSION="2.4.0" # Version of the Chainlink image to pull export CHAINLINK_ENV_USER="Satoshi-Nakamoto" # Name of the person running the tests (change to your own) export TEST_LOG_LEVEL="info" # info | debug | trace +export TEST_LOG_COLLECT="false" # true | false, whether to collect the test logs after the test is complete, this will always be done if the test fails, regardless of this setting ########## Soak/Chaos/Load Test Specific Settings ########## # Remote Runner diff --git a/integration-tests/go.mod b/integration-tests/go.mod index afd8f5e4c1..57ac78df2b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -1,6 +1,6 @@ module github.com/smartcontractkit/ccip/integration-tests -go 1.20 +go 1.21 // Make sure we're working with the latest chainlink libs replace github.com/smartcontractkit/chainlink/v2 => ../ @@ -15,20 +15,21 @@ 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/pelletier/go-toml v1.9.5 + github.com/pelletier/go-toml/v2 v2.1.0 github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chain-selectors v1.0.2 - github.com/smartcontractkit/chainlink-env v0.37.0 - github.com/smartcontractkit/chainlink-testing-framework v1.17.3-0.20230926185057-20d07b113967 + github.com/smartcontractkit/chainlink-env v0.38.0 + github.com/smartcontractkit/chainlink-testing-framework v1.17.7-0.20231005234726-62948c0c7a5e github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20230828183543-6d0939746966 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 - github.com/smartcontractkit/libocr v0.0.0-20230918212407-dbd4e505b3e6 - github.com/smartcontractkit/ocr2keepers v0.7.24 + github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6 + github.com/smartcontractkit/ocr2keepers v0.7.27 github.com/smartcontractkit/ocr2vrf v0.0.0-20230804151440-2f1eb1e20687 github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 - github.com/smartcontractkit/wasp v0.3.0 + github.com/smartcontractkit/wasp v0.3.2-0.20231007012020-8f5eb29299d7 github.com/spf13/cobra v1.7.0 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.23.0 @@ -37,7 +38,7 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.25.0 - golang.org/x/crypto v0.12.0 + golang.org/x/crypto v0.13.0 golang.org/x/sync v0.3.0 gopkg.in/guregu/null.v4 v4.0.0 ) @@ -89,6 +90,7 @@ require ( 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/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8 // 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 @@ -371,8 +373,9 @@ require ( 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/otiai10/copy v1.14.0 // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect - github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // 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 @@ -402,7 +405,7 @@ require ( 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.20230913032705-f924d753cc47 // indirect - github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230918212835-8a0b08df72a3 // indirect + github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230926113942-a871b2976dc1 // indirect github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 // indirect github.com/smartcontractkit/sqlx v1.3.5-0.20210805004948-4be295aacbeb // indirect @@ -468,11 +471,11 @@ require ( 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.14.0 // indirect + golang.org/x/net v0.15.0 // indirect golang.org/x/oauth2 v0.10.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/sys v0.12.0 // indirect + golang.org/x/term v0.12.0 // indirect + golang.org/x/text v0.13.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 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 18a253fc2e..0a3afa46bd 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -38,6 +38,7 @@ cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFO 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 v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= 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= @@ -149,6 +150,7 @@ cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvj 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 v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= 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= @@ -271,6 +273,7 @@ cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGE 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.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= 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= @@ -460,6 +463,7 @@ cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeL 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/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E= 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= @@ -528,9 +532,11 @@ cosmossdk.io/depinject v1.0.0-alpha.3/go.mod h1:eRbcdQ7MRpIPEM5YUJh8k97nxHpYbc3s 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/log v1.1.1-0.20230704160919-88f2c830b0ca/go.mod h1:PkIAKXZvaxrTRc++z53XMRvFk8AcGGWYHcMIPzVYX9c= 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= +cosmossdk.io/tools/rosetta v0.2.1/go.mod h1:Pqdc1FdvkNV3LcNIkYWt2RQY6IP1ge6YWZk8MhhO9Hw= 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= @@ -544,21 +550,31 @@ github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN 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/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= 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 v65.0.0+incompatible h1:HzKLt3kIwMm4KeJYTdx9EbjRYTySD/t8i1Ee/W5EGXw= +github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= 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 v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM= +github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= github.com/Azure/go-autorest/autorest/adal v0.9.22 h1:/GblQdIudfEM3AWWZ0mrYJQSd7JS4S/Mbzh6F0ov0Xc= +github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -579,6 +595,7 @@ github.com/Depado/ginprom v1.7.11/go.mod h1:49mxL3NTQwDrhpDbY4V1mAIB3us9B+b2hP1+ 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/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= 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= @@ -594,15 +611,19 @@ github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYr 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/Microsoft/hcsshim v0.10.0-rc.8/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= 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.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/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= 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= @@ -612,6 +633,7 @@ github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGW 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/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= 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= @@ -621,6 +643,7 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAu 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/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= 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= @@ -628,6 +651,7 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd 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/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4= +github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= 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= @@ -663,6 +687,7 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce 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/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= 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= @@ -676,6 +701,7 @@ github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/i github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= +github.com/btcsuite/btcd/btcutil v1.1.2/go.mod h1:UR7dsSJzJUfMmFiiLlIrMq1lS9jh9EdCV7FStZSnpi0= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= @@ -686,13 +712,17 @@ github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bxcodec/faker v2.0.1+incompatible h1:P0KUpUw5w6WJXwrPfv35oc91i4d8nf40Nwln+M/+faA= +github.com/bxcodec/faker v2.0.1+incompatible/go.mod h1:BNzfpVdTwnFJ6GtfYTcQu6l6rHShT+veBxNCnjCx5XM= 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/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8 h1:SjZ2GvvOononHOpK84APFuMvxqsk3tEIaKH/z4Rpu3g= +github.com/c9s/goprocinfo v0.0.0-20210130143923-c95fcf8c64a8/go.mod h1:uEyr4WpAH4hio6LFriaPkL938XnrvLpNPmQHBdrmbIE= 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= @@ -703,6 +733,7 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA 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/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -732,6 +763,7 @@ github.com/cli/go-gh/v2 v2.0.0/go.mod h1:2/ox3Dnc8wDBT5bnTAH1aKGy6Qt1ztlFBe10Euf github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI= github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= github.com/cli/shurcooL-graphql v0.0.3 h1:CtpPxyGDs136/+ZeyAfUKYmcQBjDlq5aqnrDCW5Ghh8= +github.com/cli/shurcooL-graphql v0.0.3/go.mod h1:tlrLmw/n5Q/+4qSvosT+9/W5zc8ZMjnJeYBxSdb4nWA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 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= @@ -747,10 +779,13 @@ github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWH 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/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= 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/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/apd/v3 v3.1.0 h1:MK3Ow7LH0W8zkd5GMKA1PvS9qG3bWFI95WaVNfyZJ/w= +github.com/cockroachdb/apd/v3 v3.1.0/go.mod h1:6qgPBMXjATAdD/VefbRP9NoSLKjbB4LCoA7gN4LpHs4= 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= @@ -765,6 +800,7 @@ github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ 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/coinbase/rosetta-sdk-go/types v1.0.0/go.mod h1:eq7W2TMRH22GTW0N0beDnN931DW0/WOI1R2sdHNHG4c= 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.8.0 h1:vUMDaH3ApkX8m0KZvOFFy9b5DZHBAjsnEuo9AKVZpjo= @@ -774,6 +810,7 @@ github.com/confio/ics23/go v0.9.0/go.mod h1:4LPZ2NYqnYIVRklaozjNR1FScgDJ2s5Xrp+e 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/containerd/continuity v0.4.1/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= 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= @@ -797,6 +834,7 @@ github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXy github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= +github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= 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= @@ -808,6 +846,7 @@ github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980 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/cosmos/rosetta-sdk-go v0.10.0/go.mod h1:SImAZkb96YbwvoRkzSMQB6noNJXFgWl/ENIznEoYQI4= 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/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= @@ -815,12 +854,17 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsr 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/creachadair/taskgroup v0.4.2/go.mod h1:qiXUOSrbwAY3u0JPGTzObbE3yf9hcXHDKBZ2ZjpCbgM= 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.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cucumber/common/gherkin/go/v22 v22.0.0 h1:4K8NqptbvdOrjL9DEea6HFjSpbdT9+Q5kgLpmmsHYl0= +github.com/cucumber/common/gherkin/go/v22 v22.0.0/go.mod h1:3mJT10B2GGn3MvVPd3FwR7m2u4tLhSRhWUqJU4KN4Fg= github.com/cucumber/common/messages/go/v17 v17.1.1 h1:RNqopvIFyLWnKv0LfATh34SWBhXeoFTJnSrgm9cT/Ts= +github.com/cucumber/common/messages/go/v17 v17.1.1/go.mod h1:bpGxb57tDE385Rb2EohgUadLkAbhoC4IyCFi89u/JQI= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 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= @@ -836,12 +880,14 @@ github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6Uh github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= 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/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= 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= @@ -862,6 +908,7 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA 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/digitalocean/godo v1.97.0/go.mod h1:NRpFznZFvhHjBoqZAaOD3khVzsJ3EibzKqFL4R60dmA= 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= @@ -893,11 +940,13 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go. 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/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= 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/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/esote/minmaxheap v1.0.0 h1:rgA7StnXXpZG6qlM0S7pUmEv1KpWe32rYT4x8J8ntaA= github.com/esote/minmaxheap v1.0.0/go.mod h1:Ln8+i7fS1k3PLgZI2JAo0iA1as95QnIYiGCrqSJ5FZk= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= @@ -923,13 +972,16 @@ github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw 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/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= 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/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= 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= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= @@ -1007,6 +1059,7 @@ github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= 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= @@ -1051,6 +1104,7 @@ github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhO 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/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -1067,11 +1121,13 @@ github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPr github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= 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-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= 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= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= 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= @@ -1079,6 +1135,7 @@ github.com/go-webauthn/revoke v0.1.9/go.mod h1:j6WKPnv0HovtEs++paan9g3ar46gm1Nar 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/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= 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= @@ -1120,6 +1177,7 @@ 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= github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= +github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= 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= @@ -1225,6 +1283,7 @@ github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIG 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/orderedcode v0.0.1/go.mod h1:iVyU4/qPKHY5h/wSd6rZZCDcLJNxiWO6dvsYES2Sb20= 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= @@ -1245,6 +1304,7 @@ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/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/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= 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= @@ -1270,13 +1330,16 @@ github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqE 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/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= 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/gophercloud/gophercloud v1.2.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= 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/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= 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= @@ -1341,16 +1404,20 @@ github.com/hashicorp/consul/api v1.21.0 h1:WMR2JiyuaQWRAMFaOGiYfY4Q4HRpyYRe/oYQo 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/consul/sdk v0.13.1/go.mod h1:SW/mM4LbKfqmMvcFu8v+eiQQ7oitXEFeiBe9StxERb0= github.com/hashicorp/cronexpr v1.1.1 h1:NJZDd87hGXjoZBdvyCF9mX4DCq5Wy7+A/w+A7q0wn6c= +github.com/hashicorp/cronexpr v1.1.1/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= 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-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= 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-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-getter v1.7.1/go.mod h1:W7TalhMmbPmsSMdNjD0ZskARur/9GJ17cfHTRtXV744= 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= @@ -1365,10 +1432,12 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l 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-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= 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-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= 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= @@ -1376,8 +1445,10 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv 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-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 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-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 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= @@ -1394,6 +1465,7 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p 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/nomad/api v0.0.0-20230308192510-48e7d70fcd4b/go.mod h1:bKUb1ytds5KwUioHdvdq9jmrDqCThv95si0Ub7iNeBg= 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= @@ -1402,7 +1474,9 @@ github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce/go.mod h1:+NfK9FKe 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/henvic/httpretty v0.0.6/go.mod h1:X38wLjWXHkXT7r2+uK8LjCMne9rsuNaBLJ+5cU2/Pmo= github.com/hetznercloud/hcloud-go v1.41.0 h1:KJGFRRc68QiVu4PrEP5BmCQVveCP2CM26UGQUKGpIUs= +github.com/hetznercloud/hcloud-go v1.41.0/go.mod h1:NaHg47L6C77mngZhwBG652dTAztYrsZ2/iITJKhQkHA= 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.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= @@ -1424,10 +1498,12 @@ 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/improbable-eng/grpc-web v0.15.0/go.mod h1:1sy9HKV4Jt9aEs9JSnkWlRJPuPtwNr0l57L4f878wP8= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 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/ionos-cloud/sdk-go/v6 v6.1.4/go.mod h1:Ox3W0iiEz0GHnfY9e5LmAxwklsxguuNFEUSu0gVRTME= 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= @@ -1541,6 +1617,7 @@ 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/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= 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= @@ -1552,6 +1629,7 @@ 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/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -1604,6 +1682,7 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02 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/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= 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= @@ -1847,11 +1926,13 @@ github.com/libp2p/go-yamux/v2 v2.0.0/go.mod h1:NVWira5+sVUIU6tu1JWvaRn1dRnG+cawO 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/linode/linodego v1.14.1/go.mod h1:NJlzvlNtdMRRkXb0oN6UWzUkj6t+IBsyveHgZ5Ppjyk= github.com/linxGnu/grocksdb v1.7.16 h1:Q2co1xrpdkr5Hx3Fp+f+f7fRGhQFQhvi/+226dtLmA8= github.com/linxGnu/grocksdb v1.7.16/go.mod h1:JkS7pl5qWpGpuVb3bPqTz8nC12X3YtPZT+Xq7+QfQo4= 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/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= 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= @@ -1901,6 +1982,7 @@ github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh 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/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= 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= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -1924,6 +2006,7 @@ github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0 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/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= 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= @@ -1951,6 +2034,7 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR 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/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= 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= @@ -1983,7 +2067,9 @@ github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW 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/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.12.0 h1:KuQRUE3PgxRFWhq4gHvZtPSLCGDqM5q/cYr1pZ39ytc= +github.com/muesli/termenv v0.12.0/go.mod h1:WCCv32tusQ/EEZ5S8oUIIrC/nIuBcxCVqlN4Xfkv+7A= github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= @@ -2049,6 +2135,7 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 h1:NHrXEjTNQY7P0Zfx1aMrNhpgxHmow66XQtm0aQLY0AE= +github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249/go.mod h1:mpRZBD8SJ55OIICQ3iWH0Yz3cjzA61JdqMLoWXeB2+8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -2069,6 +2156,7 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.9.7 h1:06xGQy5www2oN160RtEZoTvnP2sPhEfePYmCDc2szss= +github.com/onsi/ginkgo/v2 v2.9.7/go.mod h1:cxrmXWykAwTwhQsJOPfdIDiJ+l2RYq7U8hFU+M/1uw0= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -2096,19 +2184,27 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt 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.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= +github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= +github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= +github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= +github.com/otiai10/mint v1.5.1/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM= github.com/ovh/go-ovh v1.3.0 h1:mvZaddk4E4kLcXhzb+cxBsMPYp2pHqiQpWYkInsuZPQ= +github.com/ovh/go-ovh v1.3.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA= 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/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= 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.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -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/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/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= @@ -2189,15 +2285,20 @@ github.com/prometheus/prometheus v0.43.1-0.20230327151049-211ae4f1f0a2 h1:i5hmbB 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.6.0 h1:rcUFgcnfmuyVYDYT+4d0zfqc8YedOyruHSsUb9ImaBw= +github.com/pyroscope-io/client v0.6.0/go.mod h1:4h21iOU4pUOq0prKyDlvYRL+SCKsBc5wKiEtV+rJGqU= 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/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= 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/gocuke v0.6.2/go.mod h1:zYaqIHZobHyd0xOrHGPQjbhGJsuZ1oElx150u2o1xuk= 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/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/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= @@ -2215,6 +2316,7 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= @@ -2235,6 +2337,7 @@ github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71e 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/scaleway/scaleway-sdk-go v1.0.0-beta.14/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= 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= @@ -2244,6 +2347,7 @@ github.com/sercand/kuberesolver/v5 v5.1.0 h1:YLqreB1vUFbZHSidcqI5ChMp+RIRmop0brQ 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/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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= github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= @@ -2270,24 +2374,24 @@ github.com/smartcontractkit/chain-selectors v1.0.2 h1:IglJrBajHJ6uAFm1b2qwUcHZld github.com/smartcontractkit/chain-selectors v1.0.2/go.mod h1:WBhLlODF5b95vvx2tdKK55vGACg1+qZpuBhOGu1UXVo= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47 h1:vdieOW3CZGdD2R5zvCSMS+0vksyExPN3/Fa1uVfld/A= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20230913032705-f924d753cc47/go.mod h1:xMwqRdj5vqYhCJXgKVqvyAwdcqM6ZAEhnwEQ4Khsop8= -github.com/smartcontractkit/chainlink-env v0.37.0 h1:Yl+cMd3gzKx2217hLzDKN0EOmAjD7MrcWHzuR+knb8s= -github.com/smartcontractkit/chainlink-env v0.37.0/go.mod h1:NbRExHmJGnKSYXmvNuJx5VErSx26GtE1AEN/CRzYOg8= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230918212835-8a0b08df72a3 h1:FonaZ1kgRK0yY7D0jF5pL3K+0DYUnKcnStOOcIN+Hhg= -github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230918212835-8a0b08df72a3/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= +github.com/smartcontractkit/chainlink-env v0.38.0 h1:3LaqV5wSRCVPK0haV5jC2zdZITV2Q0BPyUMUM3tyJ7o= +github.com/smartcontractkit/chainlink-env v0.38.0/go.mod h1:ICN9gOBY+NehK8mIxxM9CrWDohgkCQ1vgX9FazCbg8I= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230926113942-a871b2976dc1 h1:Db333w+fSm2e18LMikcIQHIZqgxZruW9uCUGJLUC9mI= +github.com/smartcontractkit/chainlink-relay v0.1.7-0.20230926113942-a871b2976dc1/go.mod h1:gWclxGW7rLkbjXn7FGizYlyKhp/boekto4MEYGyiMG4= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca h1:x7M0m512gtXw5Z4B1WJPZ52VgshoIv+IvHqQ8hsH4AE= github.com/smartcontractkit/chainlink-solana v1.0.3-0.20230831134610-680240b97aca/go.mod h1:RIUJXn7EVp24TL2p4FW79dYjyno23x5mjt1nKN+5WEk= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918 h1:ByVauKFXphRlSNG47lNuxZ9aicu+r8AoNp933VRPpCw= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20230901115736-bbabe542a918/go.mod h1:/yp/sqD8Iz5GU5fcercjrw0ivJF7HDcupYg+Gjr7EPg= -github.com/smartcontractkit/chainlink-testing-framework v1.17.3-0.20230926185057-20d07b113967 h1:v/kj2OEP8Upw38bMEN5y2pAj7we53rBRvaCLzqK4ipI= -github.com/smartcontractkit/chainlink-testing-framework v1.17.3-0.20230926185057-20d07b113967/go.mod h1:izzRx4cNihkVP9XY15isSCMW1QAlRK1w5eE23/MbZHM= +github.com/smartcontractkit/chainlink-testing-framework v1.17.7-0.20231005234726-62948c0c7a5e h1:czPS4TvkFWossV21fxn969iaqtpx27o61euIE/EH/YE= +github.com/smartcontractkit/chainlink-testing-framework v1.17.7-0.20231005234726-62948c0c7a5e/go.mod h1:rypNxetVFh6bwaoHn05bsd4vCtgdEsF+1Vdyy/AhAR8= 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-20230918212407-dbd4e505b3e6 h1:w+8TI2Vcm3vk8XQz40ddcwy9BNZgoakXIby35Y54iDU= -github.com/smartcontractkit/libocr v0.0.0-20230918212407-dbd4e505b3e6/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= -github.com/smartcontractkit/ocr2keepers v0.7.24 h1:d1HcCpsBcBSC9MC9qdjzsm/NSAnnavcZAvAqPAAa75Q= -github.com/smartcontractkit/ocr2keepers v0.7.24/go.mod h1:4e1ZDRz7fpLgcRUjJpq+5mkoD0ga11BxrSp2JTWKADQ= +github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6 h1:eSo9r53fARv2MnIO5pqYvQOXMBsTlAwhHyQ6BAVp6bY= +github.com/smartcontractkit/libocr v0.0.0-20230922131214-122accb19ea6/go.mod h1:2lyRkw/qLQgUWlrWWmq5nj0y90rWeO6Y+v+fCakRgb0= +github.com/smartcontractkit/ocr2keepers v0.7.27 h1:kwqMrzmEdq6gH4yqNuLQCbdlED0KaIjwZzu3FF+Gves= +github.com/smartcontractkit/ocr2keepers v0.7.27/go.mod h1:1QGzJURnoWpysguPowOe2bshV0hNp1YX10HHlhDEsas= 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= @@ -2296,8 +2400,8 @@ github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235- github.com/smartcontractkit/tdh2/go/ocr2/decryptionplugin v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:q6f4fe39oZPdsh1i57WznEZgxd8siidMaSFq3wdPmVg= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1 h1:Dai1bn+Q5cpeGMQwRdjOdVjG8mmFFROVkSKuUgBErRQ= github.com/smartcontractkit/tdh2/go/tdh2 v0.0.0-20230906073235-9e478e5e19f1/go.mod h1:G5Sd/yzHWf26rQ+X0nG9E0buKPqRGPMJAfk2gwCzOOw= -github.com/smartcontractkit/wasp v0.3.0 h1:mueeLvpb6HyGNwILxCOKShDR6q18plQn7Gb1j3G/Qkk= -github.com/smartcontractkit/wasp v0.3.0/go.mod h1:skquNdMbKxIrHi5O8Kyukf66AaaXuEpEEaSTxfHbhak= +github.com/smartcontractkit/wasp v0.3.2-0.20231007012020-8f5eb29299d7 h1:nCD8TSoAzOAYtvJPcRozCA1EQgU5+bGvfzYjIuRhIrs= +github.com/smartcontractkit/wasp v0.3.2-0.20231007012020-8f5eb29299d7/go.mod h1:FFxNXzgJ+LU5jvyp3hmdNlpYBiivYf3wUTN+dDdFv9g= 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= @@ -2378,6 +2482,7 @@ github.com/testcontainers/testcontainers-go v0.23.0/go.mod h1:3gzuZfb7T9qfcH2pHp 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/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI= 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= @@ -2413,6 +2518,7 @@ github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95 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/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulule/limiter/v3 v3.11.2 h1:P4yOrxoEMJbOTfRJR2OzjL90oflzYPPmWg+dvwN2tHA= github.com/ulule/limiter/v3 v3.11.2/go.mod h1:QG5GnFOCV+k7lrL5Y8kgEeeflPH3+Cviqlqa8SVSQxI= github.com/umbracle/ethgo v0.1.3 h1:s8D7Rmphnt71zuqrgsGTMS5gTNbueGO1zKLh7qsFzTM= @@ -2424,6 +2530,7 @@ github.com/unrolled/secure v1.13.0/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQ 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/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= 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= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -2433,6 +2540,7 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU 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/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= 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= @@ -2462,6 +2570,7 @@ 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/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= 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= @@ -2611,8 +2720,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/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.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= 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= @@ -2760,8 +2869,8 @@ 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.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/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= 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= @@ -2940,8 +3049,9 @@ 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.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +golang.org/x/sys v0.12.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= @@ -2952,8 +3062,8 @@ 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.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/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= 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= @@ -2969,8 +3079,8 @@ 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.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/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.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= @@ -3144,6 +3254,7 @@ google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/ 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/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= 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= @@ -3411,6 +3522,7 @@ 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.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= 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= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -3442,10 +3554,12 @@ k8s.io/utils v0.0.0-20230711102312-30195339c3c7/go.mod h1:OLgZIPagt7ERELqWJFomSt lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo= +lukechampine.com/uint128 v1.3.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/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q= +modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y= 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= @@ -3453,6 +3567,7 @@ modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWs 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/ccgo/v3 v3.16.14 h1:af6KNtFgsVmnDYrWk3PQCS9XT6BXe7o3ZFJKkIKvXNQ= +modernc.org/ccgo/v3 v3.16.14/go.mod h1:mPDSujUIaTNWQSG4eqKw+atqLOEbma6Ncsa94WbC9zo= 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= @@ -3463,25 +3578,30 @@ 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/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM= +modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak= 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/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= +modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= 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/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o= +modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= 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/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA= +modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= 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/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.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= diff --git a/integration-tests/performance/cron_test.go b/integration-tests/performance/cron_test.go index c66a180356..b5fc9c48b0 100644 --- a/integration-tests/performance/cron_test.go +++ b/integration-tests/performance/cron_test.go @@ -120,10 +120,11 @@ func setupCronTest(t *testing.T) (testEnvironment *environment.Environment) { } baseTOML := `[WebServer] HTTPWriteTimout = '300s'` - cd, err := chainlink.NewDeployment(1, map[string]interface{}{ - "toml": client.AddNetworksConfig(baseTOML, network), + cd := chainlink.New(0, map[string]interface{}{ + "replicas": 1, + "toml": client.AddNetworksConfig(baseTOML, network), }) - require.NoError(t, err, "Error creating chainlink deployment") + testEnvironment = environment.New(&environment.Config{ NamespacePrefix: fmt.Sprintf("performance-cron-%s", strings.ReplaceAll(strings.ToLower(network.Name), " ", "-")), Test: t, @@ -131,8 +132,8 @@ HTTPWriteTimout = '300s'` AddHelm(mockservercfg.New(nil)). AddHelm(mockserver.New(nil)). AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() + AddHelm(cd) + err := testEnvironment.Run() require.NoError(t, err, "Error launching test environment") return testEnvironment } diff --git a/integration-tests/performance/directrequest_test.go b/integration-tests/performance/directrequest_test.go index 98c03c2bb9..1b3009043f 100644 --- a/integration-tests/performance/directrequest_test.go +++ b/integration-tests/performance/directrequest_test.go @@ -140,10 +140,11 @@ func setupDirectRequestTest(t *testing.T) (testEnvironment *environment.Environm } baseTOML := `[WebServer] HTTPWriteTimout = '300s'` - cd, err := chainlink.NewDeployment(1, map[string]interface{}{ - "toml": client.AddNetworksConfig(baseTOML, network), + cd := chainlink.New(0, map[string]interface{}{ + "replicas": 1, + "toml": client.AddNetworksConfig(baseTOML, network), }) - require.NoError(t, err, "Error creating chainlink deployment") + testEnvironment = environment.New(&environment.Config{ NamespacePrefix: fmt.Sprintf("performance-cron-%s", strings.ReplaceAll(strings.ToLower(network.Name), " ", "-")), Test: t, @@ -151,8 +152,8 @@ HTTPWriteTimout = '300s'` AddHelm(mockservercfg.New(nil)). AddHelm(mockserver.New(nil)). AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() + AddHelm(cd) + err := testEnvironment.Run() require.NoError(t, err, "Error launching test environment") return testEnvironment } diff --git a/integration-tests/performance/flux_test.go b/integration-tests/performance/flux_test.go index 2c33096a35..5ca5ae8096 100644 --- a/integration-tests/performance/flux_test.go +++ b/integration-tests/performance/flux_test.go @@ -187,10 +187,11 @@ HTTPWriteTimout = '300s' [OCR] Enabled = true` - cd, err := chainlink.NewDeployment(3, map[string]interface{}{ - "toml": client.AddNetworksConfig(baseTOML, testNetwork), + cd := chainlink.New(0, map[string]interface{}{ + "replicas": 3, + "toml": client.AddNetworksConfig(baseTOML, testNetwork), }) - require.NoError(t, err, "Error creating chainlink deployment") + testEnvironment = environment.New(&environment.Config{ NamespacePrefix: fmt.Sprintf("performance-flux-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), Test: t, @@ -198,8 +199,8 @@ Enabled = true` AddHelm(mockservercfg.New(nil)). AddHelm(mockserver.New(nil)). AddHelm(evmConf). - AddHelmCharts(cd) - err = testEnvironment.Run() + AddHelm(cd) + err := testEnvironment.Run() require.NoError(t, err, "Error running test environment") return testEnvironment, testNetwork } diff --git a/integration-tests/performance/keeper_test.go b/integration-tests/performance/keeper_test.go index 7ab0f53d0d..e1ffecd28c 100644 --- a/integration-tests/performance/keeper_test.go +++ b/integration-tests/performance/keeper_test.go @@ -153,10 +153,11 @@ TurnLookBack = 0 SyncInterval = '5s' PerformGasOverhead = 150_000` networkName := strings.ReplaceAll(strings.ToLower(network.Name), " ", "-") - cd, err := chainlink.NewDeployment(5, map[string]interface{}{ - "toml": client.AddNetworksConfig(baseTOML, network), + cd := chainlink.New(0, map[string]interface{}{ + "replicas": 5, + "toml": client.AddNetworksConfig(baseTOML, network), }) - require.NoError(t, err, "Error creating chainlink deployment") + testEnvironment := environment.New( &environment.Config{ NamespacePrefix: fmt.Sprintf("performance-keeper-%s-%s", testName, networkName), @@ -166,8 +167,8 @@ PerformGasOverhead = 150_000` AddHelm(mockservercfg.New(nil)). AddHelm(mockserver.New(nil)). AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() + AddHelm(cd) + err := testEnvironment.Run() require.NoError(t, err, "Error deploying test environment") if testEnvironment.WillUseRemoteRunner() { return testEnvironment, nil, nil, nil, nil diff --git a/integration-tests/performance/ocr_test.go b/integration-tests/performance/ocr_test.go index d3d2904965..3df0700c6e 100644 --- a/integration-tests/performance/ocr_test.go +++ b/integration-tests/performance/ocr_test.go @@ -107,10 +107,11 @@ Enabled = true Enabled = true ListenIP = '0.0.0.0' ListenPort = 6690` - cd, err := chainlink.NewDeployment(6, map[string]interface{}{ - "toml": client.AddNetworksConfig(baseTOML, testNetwork), + cd := chainlink.New(0, map[string]interface{}{ + "replicas": 6, + "toml": client.AddNetworksConfig(baseTOML, testNetwork), }) - require.NoError(t, err, "Error creating chainlink deployment") + testEnvironment = environment.New(&environment.Config{ NamespacePrefix: fmt.Sprintf("performance-ocr-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), Test: t, @@ -118,8 +119,8 @@ ListenPort = 6690` AddHelm(mockservercfg.New(nil)). AddHelm(mockserver.New(nil)). AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() + AddHelm(cd) + err := testEnvironment.Run() require.NoError(t, err, "Error running test environment") return testEnvironment, testNetwork } diff --git a/integration-tests/performance/vrf_test.go b/integration-tests/performance/vrf_test.go index af3a3ecba8..4f86c6585b 100644 --- a/integration-tests/performance/vrf_test.go +++ b/integration-tests/performance/vrf_test.go @@ -146,17 +146,17 @@ func setupVRFTest(t *testing.T) (testEnvironment *environment.Environment, testN } baseTOML := `[WebServer] HTTPWriteTimout = '300s'` - cd, err := chainlink.NewDeployment(0, map[string]interface{}{ + cd := chainlink.New(0, 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-vrf-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), Test: t, }). AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() + AddHelm(cd) + err := testEnvironment.Run() require.NoError(t, err, "Error running test environment") return testEnvironment, testNetwork } diff --git a/integration-tests/reorg/automation_reorg_test.go b/integration-tests/reorg/automation_reorg_test.go index ab439e59f2..2f8db75f74 100644 --- a/integration-tests/reorg/automation_reorg_test.go +++ b/integration-tests/reorg/automation_reorg_test.go @@ -77,7 +77,7 @@ LimitDefault = 5_000_000` "networkId": "1337", }, "miner": map[string]interface{}{ - "replicas": "2", + "replicas": 2, }, }, }, @@ -126,9 +126,9 @@ const ( func TestAutomationReorg(t *testing.T) { l := logging.GetTestLogger(t) network := networks.SelectedNetwork + defaultAutomationSettings["replicas"] = numberOfNodes + cd := chainlink.New(0, defaultAutomationSettings) - cd, err := chainlink.NewDeployment(numberOfNodes, defaultAutomationSettings) - require.NoError(t, err, "Error creating chainlink deployment") testEnvironment := environment. New(&environment.Config{ NamespacePrefix: fmt.Sprintf("automation-reorg-%d", automationReorgBlocks), @@ -139,8 +139,8 @@ func TestAutomationReorg(t *testing.T) { Name: "geth-blockscout", WsURL: activeEVMNetwork.URL, HttpURL: activeEVMNetwork.HTTPURLs[0]})). - AddHelmCharts(cd) - err = testEnvironment.Run() + AddHelm(cd) + err := testEnvironment.Run() require.NoError(t, err, "Error setting up test environment") if testEnvironment.WillUseRemoteRunner() { diff --git a/integration-tests/reorg/reorg_test.go b/integration-tests/reorg/reorg_test.go index 5666d8c754..74468b9253 100644 --- a/integration-tests/reorg/reorg_test.go +++ b/integration-tests/reorg/reorg_test.go @@ -125,11 +125,12 @@ func TestDirectRequestReorg(t *testing.T) { time.Sleep(90 * time.Second) activeEVMNetwork = networks.SimulatedEVMNonDev netCfg := fmt.Sprintf(networkDRTOML, EVMFinalityDepth, EVMTrackerHistoryDepth) - chainlinkDeployment, err := chainlink.NewDeployment(1, map[string]interface{}{ - "toml": client.AddNetworkDetailedConfig(baseDRTOML, netCfg, activeEVMNetwork), + chainlinkDeployment := chainlink.New(0, map[string]interface{}{ + "replicas": 1, + "toml": client.AddNetworkDetailedConfig(baseDRTOML, netCfg, activeEVMNetwork), }) - require.NoError(t, err, "Error building Chainlink deployment") - err = testEnvironment.AddHelmCharts(chainlinkDeployment).Run() + + err = testEnvironment.AddHelm(chainlinkDeployment).Run() require.NoError(t, err, "Error adding to test environment") chainClient, err := blockchain.NewEVMClient(networkSettings, testEnvironment, l) diff --git a/integration-tests/smoke/automation_test.go b/integration-tests/smoke/automation_test.go index 76ee75b21b..0eabac7844 100644 --- a/integration-tests/smoke/automation_test.go +++ b/integration-tests/smoke/automation_test.go @@ -1005,13 +1005,22 @@ func setupAutomationTestDocker( clNodeConfig.P2P.V2.AnnounceAddresses = &[]string{"0.0.0.0:6690"} clNodeConfig.P2P.V2.ListenAddresses = &[]string{"0.0.0.0:6690"} - // launch the environment + secretsConfig := ` + [Mercury.Credentials.cred1] + LegacyURL = 'http://localhost:53299' + URL = 'http://localhost:53299' + Username = 'node' + Password = 'nodepass' + ` + + //launch the environment env, err := test_env.NewCLTestEnvBuilder(). WithTestLogger(t). WithGeth(). WithMockServer(1). WithCLNodes(5). WithCLNodeConfig(clNodeConfig). + WithSecretsConfig(secretsConfig). WithFunding(big.NewFloat(.5)). Build() require.NoError(t, err, "Error deploying test environment") diff --git a/integration-tests/smoke/forwarders_ocr2_test.go b/integration-tests/smoke/forwarders_ocr2_test.go index 2f7c4fa21d..48d1d20b4d 100644 --- a/integration-tests/smoke/forwarders_ocr2_test.go +++ b/integration-tests/smoke/forwarders_ocr2_test.go @@ -13,6 +13,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink/integration-tests/actions" + "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" ) @@ -73,7 +74,8 @@ func TestForwarderOCR2Basic(t *testing.T) { transmitters = append(transmitters, forwarderCommonAddress.Hex()) } - ocrInstances, err := actions.DeployOCRv2Contracts(1, linkTokenContract, env.ContractDeployer, transmitters, env.EVMClient) + ocrOffchainOptions := contracts.DefaultOffChainAggregatorOptions() + ocrInstances, err := actions.DeployOCRv2Contracts(1, linkTokenContract, env.ContractDeployer, transmitters, env.EVMClient, ocrOffchainOptions) require.NoError(t, err, "Error deploying OCRv2 contracts with forwarders") err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") @@ -83,7 +85,7 @@ func TestForwarderOCR2Basic(t *testing.T) { err = env.EVMClient.WaitForEvents() require.NoError(t, err, "Error waiting for events") - ocrv2Config, err := actions.BuildMedianOCR2ConfigLocal(workerNodes) + ocrv2Config, err := actions.BuildMedianOCR2ConfigLocal(workerNodes, ocrOffchainOptions) require.NoError(t, err, "Error building OCRv2 config") ocrv2Config.Transmitters = authorizedForwarders diff --git a/integration-tests/smoke/ocr2_test.go b/integration-tests/smoke/ocr2_test.go index db11f187f5..c6804e48d0 100644 --- a/integration-tests/smoke/ocr2_test.go +++ b/integration-tests/smoke/ocr2_test.go @@ -22,6 +22,7 @@ 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/docker/test_env" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" ) @@ -69,13 +70,14 @@ func TestOCRv2Basic(t *testing.T) { transmitters = append(transmitters, addr) } - aggregatorContracts, err := actions.DeployOCRv2Contracts(1, linkToken, env.ContractDeployer, transmitters, env.EVMClient) + ocrOffchainOptions := contracts.DefaultOffChainAggregatorOptions() + aggregatorContracts, err := actions.DeployOCRv2Contracts(1, linkToken, env.ContractDeployer, transmitters, env.EVMClient, ocrOffchainOptions) require.NoError(t, err, "Error deploying OCRv2 aggregator contracts") 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.BuildMedianOCR2ConfigLocal(workerNodes) + ocrv2Config, err := actions.BuildMedianOCR2ConfigLocal(workerNodes, ocrOffchainOptions) require.NoError(t, err, "Error building OCRv2 config") err = actions.ConfigureOCRv2AggregatorContracts(env.EVMClient, ocrv2Config, aggregatorContracts) @@ -124,10 +126,10 @@ func setupOCR2Test(t *testing.T, forwardersEnabled bool) ( toml = client.AddNetworksConfig(config.BaseOCR2Config, testNetwork) } - chainlinkChart, err := chainlink.NewDeployment(6, map[string]interface{}{ - "toml": toml, + chainlinkChart := chainlink.New(0, map[string]interface{}{ + "replicas": 6, + "toml": toml, }) - require.NoError(t, err, "Error creating chainlink deployment") testEnvironment = environment.New(&environment.Config{ NamespacePrefix: fmt.Sprintf("smoke-ocr2-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), @@ -136,8 +138,8 @@ func setupOCR2Test(t *testing.T, forwardersEnabled bool) ( AddHelm(mockservercfg.New(nil)). AddHelm(mockserver.New(nil)). AddHelm(evmConfig). - AddHelmCharts(chainlinkChart) - err = testEnvironment.Run() + AddHelm(chainlinkChart) + err := testEnvironment.Run() require.NoError(t, err, "Error running test environment") return testEnvironment, testNetwork } diff --git a/integration-tests/smoke/ocr2vrf_test.go b/integration-tests/smoke/ocr2vrf_test.go index c9f689ca7a..8148863918 100644 --- a/integration-tests/smoke/ocr2vrf_test.go +++ b/integration-tests/smoke/ocr2vrf_test.go @@ -159,21 +159,22 @@ func setupOCR2VRFEnvironment(t *testing.T) (testEnvironment *environment.Environ }) } - cd, err := chainlink.NewDeployment(6, map[string]interface{}{ + cd := chainlink.New(0, map[string]interface{}{ + "replicas": 6, "toml": client.AddNetworkDetailedConfig( config.BaseOCR2Config, config.DefaultOCR2VRFNetworkDetailTomlConfig, testNetwork, ), }) - require.NoError(t, err, "Error creating Chainlink deployment") + testEnvironment = environment.New(&environment.Config{ NamespacePrefix: fmt.Sprintf("smoke-ocr2vrf-%s", strings.ReplaceAll(strings.ToLower(testNetwork.Name), " ", "-")), Test: t, }). AddHelm(evmConfig). - AddHelmCharts(cd) - err = testEnvironment.Run() + AddHelm(cd) + err := testEnvironment.Run() require.NoError(t, err, "Error running test environment") diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index f21ca2d3c6..e26a4ed6b1 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -2,11 +2,13 @@ package smoke import ( "context" - "github.com/pkg/errors" "math/big" "testing" "time" + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-testing-framework/logging" @@ -25,7 +27,7 @@ func TestVRFv2PlusBilling(t *testing.T) { WithTestLogger(t). WithGeth(). WithCLNodes(1). - WithFunding(vrfv2plus_constants.ChainlinkNodeFundingAmountEth). + WithFunding(vrfv2plus_constants.ChainlinkNodeFundingAmountNative). Build() require.NoError(t, err, "error creating test env") t.Cleanup(func() { @@ -36,23 +38,23 @@ func TestVRFv2PlusBilling(t *testing.T) { env.ParallelTransactions(true) - mockETHLinkFeedAddress, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, vrfv2plus_constants.LinkEthFeedResponse) + mockETHLinkFeed, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, vrfv2plus_constants.LinkNativeFeedResponse) require.NoError(t, err, "error deploying mock ETH/LINK feed") - linkAddress, err := actions.DeployLINKToken(env.ContractDeployer) + linkToken, err := actions.DeployLINKToken(env.ContractDeployer) require.NoError(t, err, "error deploying LINK contract") - vrfv2PlusContracts, subID, vrfv2PlusData, err := vrfv2plus.SetupVRFV2PlusEnvironment(env, linkAddress, mockETHLinkFeedAddress, 1) - require.NoError(t, err, "error setting up VRF v2 Plus env") + vrfv2PlusContracts, subID, vrfv2PlusData, err := vrfv2plus.SetupVRFV2_5Environment(env, linkToken, mockETHLinkFeed, 1) + require.NoError(t, err, "error setting up VRF v2_5 env") subscription, err := vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID) require.NoError(t, err, "error getting subscription information") l.Debug(). - Interface("Juels Balance", subscription.Balance). - Interface("Native Token Balance", subscription.EthBalance). - Interface("Subscription ID", subID). - Interface("Subscription Owner", subscription.Owner.String()). + Str("Juels Balance", subscription.Balance.String()). + Str("Native Token Balance", subscription.NativeBalance.String()). + Str("Subscription ID", subID.String()). + Str("Subscription Owner", subscription.Owner.String()). Interface("Subscription Consumers", subscription.Consumers). Msg("Subscription Data") @@ -87,18 +89,18 @@ func TestVRFv2PlusBilling(t *testing.T) { status, err := vrfv2PlusContracts.LoadTestConsumers[0].GetRequestStatus(context.Background(), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) - l.Debug().Interface("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") + l.Debug().Bool("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") require.Equal(t, vrfv2plus_constants.NumberOfWords, uint32(len(status.RandomWords))) for _, w := range status.RandomWords { l.Info().Str("Output", w.String()).Msg("Randomness fulfilled") - require.Equal(t, w.Cmp(big.NewInt(0)), 1, "Expected the VRF job give an answer bigger than 0") + require.Equal(t, 1, w.Cmp(big.NewInt(0)), "Expected the VRF job give an answer bigger than 0") } }) t.Run("VRFV2 Plus With Native Billing", func(t *testing.T) { var isNativeBilling = true - subNativeTokenBalanceBeforeRequest := subscription.EthBalance + subNativeTokenBalanceBeforeRequest := subscription.NativeBalance jobRunsBeforeTest, err := env.CLNodes[0].API.MustReadRunsByJob(vrfv2PlusData.VRFJob.Data.ID) require.NoError(t, err, "error reading job runs") @@ -116,7 +118,7 @@ func TestVRFv2PlusBilling(t *testing.T) { expectedSubBalanceWei := new(big.Int).Sub(subNativeTokenBalanceBeforeRequest, randomWordsFulfilledEvent.Payment) subscription, err = vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID) require.NoError(t, err) - subBalanceAfterRequest := subscription.EthBalance + subBalanceAfterRequest := subscription.NativeBalance require.Equal(t, expectedSubBalanceWei, subBalanceAfterRequest) jobRuns, err := env.CLNodes[0].API.MustReadRunsByJob(vrfv2PlusData.VRFJob.Data.ID) @@ -126,12 +128,138 @@ func TestVRFv2PlusBilling(t *testing.T) { status, err := vrfv2PlusContracts.LoadTestConsumers[0].GetRequestStatus(context.Background(), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) - l.Debug().Interface("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") + l.Debug().Bool("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") require.Equal(t, vrfv2plus_constants.NumberOfWords, uint32(len(status.RandomWords))) for _, w := range status.RandomWords { l.Info().Str("Output", w.String()).Msg("Randomness fulfilled") - require.Equal(t, w.Cmp(big.NewInt(0)), 1, "Expected the VRF job give an answer bigger than 0") + require.Equal(t, 1, w.Cmp(big.NewInt(0)), "Expected the VRF job give an answer bigger than 0") + } + }) + + wrapperContracts, wrapperSubID, err := vrfv2plus.SetupVRFV2PlusWrapperEnvironment( + env, + linkToken, + mockETHLinkFeed, + vrfv2PlusContracts.Coordinator, + vrfv2PlusData.KeyHash, + 1, + ) + require.NoError(t, err) + + t.Run("VRFV2 Plus With Direct Funding (VRFV2PlusWrapper) - Link Billing", func(t *testing.T) { + var isNativeBilling = false + + wrapperConsumerJuelsBalanceBeforeRequest, err := linkToken.BalanceOf(context.Background(), wrapperContracts.LoadTestConsumers[0].Address()) + require.NoError(t, err, "error getting wrapper consumer balance") + + wrapperSubscription, err := vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), wrapperSubID) + require.NoError(t, err, "error getting subscription information") + subBalanceBeforeRequest := wrapperSubscription.Balance + + randomWordsFulfilledEvent, err := vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillment( + wrapperContracts.LoadTestConsumers[0], + vrfv2PlusContracts.Coordinator, + vrfv2PlusData, + wrapperSubID, + isNativeBilling, + l, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + + expectedSubBalanceJuels := new(big.Int).Sub(subBalanceBeforeRequest, randomWordsFulfilledEvent.Payment) + wrapperSubscription, err = vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), wrapperSubID) + require.NoError(t, err, "error getting subscription information") + subBalanceAfterRequest := wrapperSubscription.Balance + require.Equal(t, expectedSubBalanceJuels, subBalanceAfterRequest) + + consumerStatus, err := wrapperContracts.LoadTestConsumers[0].GetRequestStatus(context.Background(), randomWordsFulfilledEvent.RequestId) + require.NoError(t, err, "error getting rand request status") + require.True(t, consumerStatus.Fulfilled) + + expectedWrapperConsumerJuelsBalance := new(big.Int).Sub(wrapperConsumerJuelsBalanceBeforeRequest, consumerStatus.Paid) + + wrapperConsumerJuelsBalanceAfterRequest, err := linkToken.BalanceOf(context.Background(), wrapperContracts.LoadTestConsumers[0].Address()) + require.NoError(t, err, "error getting wrapper consumer balance") + require.Equal(t, expectedWrapperConsumerJuelsBalance, wrapperConsumerJuelsBalanceAfterRequest) + + //todo: uncomment when VRF-651 will be fixed + //require.Equal(t, 1, consumerStatus.Paid.Cmp(randomWordsFulfilledEvent.Payment), "Expected Consumer contract pay more than the Coordinator Sub") + l.Debug(). + Str("Consumer Balance Before Request (Juels)", wrapperConsumerJuelsBalanceBeforeRequest.String()). + Str("Consumer Balance After Request (Juels)", wrapperConsumerJuelsBalanceAfterRequest.String()). + Bool("Fulfilment Status", consumerStatus.Fulfilled). + Str("Paid in Juels by Consumer Contract", consumerStatus.Paid.String()). + Str("Paid in Juels by Coordinator Sub", randomWordsFulfilledEvent.Payment.String()). + Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). + Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). + Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). + Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Msg("Random Words Request Fulfilment Status") + + require.Equal(t, vrfv2plus_constants.NumberOfWords, uint32(len(consumerStatus.RandomWords))) + for _, w := range consumerStatus.RandomWords { + l.Info().Str("Output", w.String()).Msg("Randomness fulfilled") + require.Equal(t, 1, w.Cmp(big.NewInt(0)), "Expected the VRF job give an answer bigger than 0") + } + }) + + t.Run("VRFV2 Plus With Direct Funding (VRFV2PlusWrapper) - Native Billing", func(t *testing.T) { + var isNativeBilling = true + + wrapperConsumerBalanceBeforeRequestWei, err := env.EVMClient.BalanceAt(context.Background(), common.HexToAddress(wrapperContracts.LoadTestConsumers[0].Address())) + require.NoError(t, err, "error getting wrapper consumer balance") + + wrapperSubscription, err := vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), wrapperSubID) + require.NoError(t, err, "error getting subscription information") + subBalanceBeforeRequest := wrapperSubscription.NativeBalance + + randomWordsFulfilledEvent, err := vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillment( + wrapperContracts.LoadTestConsumers[0], + vrfv2PlusContracts.Coordinator, + vrfv2PlusData, + wrapperSubID, + isNativeBilling, + l, + ) + require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + + expectedSubBalanceWei := new(big.Int).Sub(subBalanceBeforeRequest, randomWordsFulfilledEvent.Payment) + wrapperSubscription, err = vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), wrapperSubID) + require.NoError(t, err, "error getting subscription information") + subBalanceAfterRequest := wrapperSubscription.NativeBalance + require.Equal(t, expectedSubBalanceWei, subBalanceAfterRequest) + + consumerStatus, err := wrapperContracts.LoadTestConsumers[0].GetRequestStatus(context.Background(), randomWordsFulfilledEvent.RequestId) + require.NoError(t, err, "error getting rand request status") + require.True(t, consumerStatus.Fulfilled) + + expectedWrapperConsumerWeiBalance := new(big.Int).Sub(wrapperConsumerBalanceBeforeRequestWei, consumerStatus.Paid) + + wrapperConsumerBalanceAfterRequestWei, err := env.EVMClient.BalanceAt(context.Background(), common.HexToAddress(wrapperContracts.LoadTestConsumers[0].Address())) + require.NoError(t, err, "error getting wrapper consumer balance") + require.Equal(t, expectedWrapperConsumerWeiBalance, wrapperConsumerBalanceAfterRequestWei) + + //todo: uncomment when VRF-651 will be fixed + //require.Equal(t, 1, consumerStatus.Paid.Cmp(randomWordsFulfilledEvent.Payment), "Expected Consumer contract pay more than the Coordinator Sub") + l.Debug(). + Str("Consumer Balance Before Request (WEI)", wrapperConsumerBalanceBeforeRequestWei.String()). + Str("Consumer Balance After Request (WEI)", wrapperConsumerBalanceAfterRequestWei.String()). + Bool("Fulfilment Status", consumerStatus.Fulfilled). + Str("Paid in Juels by Consumer Contract", consumerStatus.Paid.String()). + Str("Paid in Juels by Coordinator Sub", randomWordsFulfilledEvent.Payment.String()). + Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). + Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). + Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). + Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Msg("Random Words Request Fulfilment Status") + + require.Equal(t, vrfv2plus_constants.NumberOfWords, uint32(len(consumerStatus.RandomWords))) + for _, w := range consumerStatus.RandomWords { + l.Info().Str("Output", w.String()).Msg("Randomness fulfilled") + require.Equal(t, 1, w.Cmp(big.NewInt(0)), "Expected the VRF job give an answer bigger than 0") } }) @@ -144,7 +272,7 @@ func TestVRFv2PlusMigration(t *testing.T) { WithTestLogger(t). WithGeth(). WithCLNodes(1). - WithFunding(vrfv2plus_constants.ChainlinkNodeFundingAmountEth). + WithFunding(vrfv2plus_constants.ChainlinkNodeFundingAmountNative). Build() require.NoError(t, err, "error creating test env") t.Cleanup(func() { @@ -155,23 +283,23 @@ func TestVRFv2PlusMigration(t *testing.T) { env.ParallelTransactions(true) - mockETHLinkFeedAddress, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, vrfv2plus_constants.LinkEthFeedResponse) + mockETHLinkFeedAddress, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, vrfv2plus_constants.LinkNativeFeedResponse) require.NoError(t, err, "error deploying mock ETH/LINK feed") linkAddress, err := actions.DeployLINKToken(env.ContractDeployer) require.NoError(t, err, "error deploying LINK contract") - vrfv2PlusContracts, subID, vrfv2PlusData, err := vrfv2plus.SetupVRFV2PlusEnvironment(env, linkAddress, mockETHLinkFeedAddress, 2) - require.NoError(t, err, "error setting up VRF v2 Plus env") + vrfv2PlusContracts, subID, vrfv2PlusData, err := vrfv2plus.SetupVRFV2_5Environment(env, linkAddress, mockETHLinkFeedAddress, 2) + require.NoError(t, err, "error setting up VRF v2_5 env") subscription, err := vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID) require.NoError(t, err, "error getting subscription information") l.Debug(). - Interface("Juels Balance", subscription.Balance). - Interface("Native Token Balance", subscription.EthBalance). - Interface("Subscription ID", subID). - Interface("Subscription Owner", subscription.Owner.String()). + Str("Juels Balance", subscription.Balance.String()). + Str("Native Token Balance", subscription.NativeBalance.String()). + Str("Subscription ID", subID.String()). + Str("Subscription Owner", subscription.Owner.String()). Interface("Subscription Consumers", subscription.Consumers). Msg("Subscription Data") @@ -198,12 +326,12 @@ func TestVRFv2PlusMigration(t *testing.T) { vrfv2plus_constants.MaxGasLimitVRFCoordinatorConfig, vrfv2plus_constants.StalenessSeconds, vrfv2plus_constants.GasAfterPaymentCalculation, - vrfv2plus_constants.LinkEthFeedResponse, + vrfv2plus_constants.LinkNativeFeedResponse, vrfv2plus_constants.VRFCoordinatorV2PlusUpgradedVersionFeeConfig, ) - err = newCoordinator.SetLINKAndLINKETHFeed(linkAddress.Address(), mockETHLinkFeedAddress.Address()) - require.NoError(t, err, vrfv2plus.ErrSetLinkETHLinkFeed) + err = newCoordinator.SetLINKAndLINKNativeFeed(linkAddress.Address(), mockETHLinkFeedAddress.Address()) + require.NoError(t, err, vrfv2plus.ErrSetLinkNativeLinkFeed) err = env.EVMClient.WaitForEvents() require.NoError(t, err, vrfv2plus.ErrWaitTXsComplete) @@ -255,11 +383,11 @@ func TestVRFv2PlusMigration(t *testing.T) { require.NoError(t, err, "error getting subscription information") l.Debug(). - Interface("New Coordinator", newCoordinator.Address()). - Interface("Subscription ID", subID). - Interface("Juels Balance", migratedSubscription.Balance). - Interface("Native Token Balance", migratedSubscription.EthBalance). - Interface("Subscription Owner", migratedSubscription.Owner.String()). + Str("New Coordinator", newCoordinator.Address()). + Str("Subscription ID", subID.String()). + Str("Juels Balance", migratedSubscription.Balance.String()). + Str("Native Token Balance", migratedSubscription.NativeBalance.String()). + Str("Subscription Owner", migratedSubscription.Owner.String()). Interface("Subscription Consumers", migratedSubscription.Consumers). Msg("Subscription Data After Migration to New Coordinator") @@ -269,13 +397,13 @@ func TestVRFv2PlusMigration(t *testing.T) { require.NoError(t, err, "error getting Coordinator from Consumer contract") require.Equal(t, newCoordinator.Address(), coordinatorAddressInConsumerAfterMigration.String()) l.Debug(). - Interface("Consumer", consumer.Address()). - Interface("Coordinator", coordinatorAddressInConsumerAfterMigration). + Str("Consumer", consumer.Address()). + Str("Coordinator", coordinatorAddressInConsumerAfterMigration.String()). Msg("Coordinator Address in Consumer After Migration") } //Verify old and migrated subs - require.Equal(t, oldSubscriptionBeforeMigration.EthBalance, migratedSubscription.EthBalance) + require.Equal(t, oldSubscriptionBeforeMigration.NativeBalance, migratedSubscription.NativeBalance) require.Equal(t, oldSubscriptionBeforeMigration.Balance, migratedSubscription.Balance) require.Equal(t, oldSubscriptionBeforeMigration.Owner, migratedSubscription.Owner) require.Equal(t, oldSubscriptionBeforeMigration.Consumers, migratedSubscription.Consumers) @@ -294,10 +422,10 @@ func TestVRFv2PlusMigration(t *testing.T) { //Verify that total balances changed for Link and Eth for new and old coordinator expectedLinkTotalBalanceForMigratedCoordinator := new(big.Int).Add(oldSubscriptionBeforeMigration.Balance, migratedCoordinatorLinkTotalBalanceBeforeMigration) - expectedEthTotalBalanceForMigratedCoordinator := new(big.Int).Add(oldSubscriptionBeforeMigration.EthBalance, migratedCoordinatorEthTotalBalanceBeforeMigration) + expectedEthTotalBalanceForMigratedCoordinator := new(big.Int).Add(oldSubscriptionBeforeMigration.NativeBalance, migratedCoordinatorEthTotalBalanceBeforeMigration) expectedLinkTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorLinkTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.Balance) - expectedEthTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorEthTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.EthBalance) + expectedEthTotalBalanceForOldCoordinator := new(big.Int).Sub(oldCoordinatorEthTotalBalanceBeforeMigration, oldSubscriptionBeforeMigration.NativeBalance) require.Equal(t, expectedLinkTotalBalanceForMigratedCoordinator, migratedCoordinatorLinkTotalBalanceAfterMigration) require.Equal(t, expectedEthTotalBalanceForMigratedCoordinator, migratedCoordinatorEthTotalBalanceAfterMigration) require.Equal(t, expectedLinkTotalBalanceForOldCoordinator, oldCoordinatorLinkTotalBalanceAfterMigration) diff --git a/integration-tests/testsetups/ocr.go b/integration-tests/testsetups/ocr.go index 5f12995cc0..b53fe9a797 100644 --- a/integration-tests/testsetups/ocr.go +++ b/integration-tests/testsetups/ocr.go @@ -136,13 +136,14 @@ func (o *OCRSoakTest) DeployEnvironment(customChainlinkNetworkTOML string) { Test: o.t, } - cd, err := chainlink.NewDeployment(6, map[string]any{ - "toml": client.AddNetworkDetailedConfig(config.BaseOCRP2PV1Config, customChainlinkNetworkTOML, network), + cd := chainlink.New(0, map[string]any{ + "replicas": 6, + "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)). @@ -151,8 +152,8 @@ func (o *OCRSoakTest) DeployEnvironment(customChainlinkNetworkTOML string) { Simulated: network.Simulated, WsURLs: network.URLs, })). - AddHelmCharts(cd) - err = testEnvironment.Run() + AddHelm(cd) + err := testEnvironment.Run() require.NoError(o.t, err, "Error launching test environment") o.testEnvironment = testEnvironment o.namespace = testEnvironment.Cfg.Namespace @@ -555,14 +556,13 @@ func (o *OCRSoakTest) setFilterQuery() { func (o *OCRSoakTest) observeOCREvents() error { eventLogs := make(chan types.Log) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() eventSub, err := o.chainClient.SubscribeFilterLogs(ctx, o.filterQuery, eventLogs) + cancel() if err != nil { return err } go func() { - defer cancel() for { select { case event := <-eventLogs: @@ -589,6 +589,7 @@ func (o *OCRSoakTest) observeOCREvents() error { Msg("Error while subscribed to OCR Logs. Resubscribing") ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second) eventSub, err = o.chainClient.SubscribeFilterLogs(ctx, o.filterQuery, eventLogs) + cancel() } } } diff --git a/integration-tests/utils/templates/secrets.go b/integration-tests/utils/templates/secrets.go index 3d3f9e44a9..f81287e871 100644 --- a/integration-tests/utils/templates/secrets.go +++ b/integration-tests/utils/templates/secrets.go @@ -8,10 +8,11 @@ import ( // 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 + PgDbName string + PgHost string + PgPort string + PgPassword string + CustomSecrets string } func (c NodeSecretsTemplate) String() (string, error) { @@ -22,11 +23,14 @@ URL = 'postgresql://postgres:{{ .PgPassword }}@{{ .PgHost }}:{{ .PgPort }}/{{ .P [Password] Keystore = '................' # Required +{{ if .CustomSecrets }} + {{ .CustomSecrets }} +{{ else }} [Mercury.Credentials.cred1] -# URL = 'http://host.docker.internal:3000/reports' URL = 'localhost:1338' Username = 'node' Password = 'nodepass' +{{ end }} ` return templates.MarshalTemplate(c, uuid.NewString(), tpl) } diff --git a/operator_ui/TAG b/operator_ui/TAG index 10da1e7ab2..6762dd4e0f 100644 --- a/operator_ui/TAG +++ b/operator_ui/TAG @@ -1 +1 @@ -v0.8.0-197331a +v0.8.0-a8fbbb3 diff --git a/plugins/chainlink.Dockerfile b/plugins/chainlink.Dockerfile index f983c18d1a..6f713e078a 100644 --- a/plugins/chainlink.Dockerfile +++ b/plugins/chainlink.Dockerfile @@ -1,5 +1,5 @@ # Build image: Chainlink binary -FROM golang:1.20-buster as buildgo +FROM golang:1.21-bullseye as buildgo RUN go version WORKDIR /chainlink diff --git a/plugins/cmd/chainlink-median/main.go b/plugins/cmd/chainlink-median/main.go index 4d96654852..00836fa7c2 100644 --- a/plugins/cmd/chainlink-median/main.go +++ b/plugins/cmd/chainlink-median/main.go @@ -14,7 +14,7 @@ const ( ) func main() { - s := plugins.StartServer(loggerName) + s := plugins.MustNewStartedServer(loggerName) defer s.Stop() p := median.NewPlugin(s.Logger) diff --git a/plugins/cmd/chainlink-solana/main.go b/plugins/cmd/chainlink-solana/main.go index 132d7244fd..ec30fa59f4 100644 --- a/plugins/cmd/chainlink-solana/main.go +++ b/plugins/cmd/chainlink-solana/main.go @@ -21,7 +21,7 @@ const ( ) func main() { - s := plugins.StartServer(loggerName) + s := plugins.MustNewStartedServer(loggerName) defer s.Stop() p := &pluginRelayer{Base: plugins.Base{Logger: s.Logger}} diff --git a/plugins/cmd/chainlink-starknet/main.go b/plugins/cmd/chainlink-starknet/main.go index aa69c85fe4..1052f3c1fc 100644 --- a/plugins/cmd/chainlink-starknet/main.go +++ b/plugins/cmd/chainlink-starknet/main.go @@ -21,7 +21,7 @@ const ( ) func main() { - s := plugins.StartServer(loggerName) + s := plugins.MustNewStartedServer(loggerName) defer s.Stop() p := &pluginRelayer{Base: plugins.Base{Logger: s.Logger}} diff --git a/plugins/plugin.go b/plugins/plugin.go index dff3345efd..0b93ef26f5 100644 --- a/plugins/plugin.go +++ b/plugins/plugin.go @@ -32,7 +32,7 @@ func (p *Base) HealthReport() map[string]error { p.mu.RLock() defer p.mu.RUnlock() for _, s := range p.srvs { - maps.Copy(s.HealthReport(), hr) + maps.Copy(hr, s.HealthReport()) } return hr } diff --git a/plugins/server.go b/plugins/server.go index 0d0e0dc62c..3b0348a68b 100644 --- a/plugins/server.go +++ b/plugins/server.go @@ -9,47 +9,78 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services" ) -// StartServer returns a started Server. +// NewStartedServer returns a started Server. // The caller is responsible for calling Server.Stop(). -func StartServer(loggerName string) *Server { - s := Server{ +func NewStartedServer(loggerName string) (*Server, error) { + s, err := newServer(loggerName) + if err != nil { + return nil, err + } + err = s.start() + if err != nil { + return nil, err + } + + return s, nil +} + +// MustNewStartedServer returns a new started Server like NewStartedServer, but logs and exits in the event of error. +// The caller is responsible for calling Server.Stop(). +func MustNewStartedServer(loggerName string) *Server { + s, err := newServer(loggerName) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to start server: %s\n", err) + os.Exit(1) + } + err = s.start() + if err != nil { + s.Logger.Fatalf("Failed to start server: %s", err) + } + + return s +} + +// Server holds common plugin server fields. +type Server struct { + loop.GRPCOpts + Logger logger.SugaredLogger + *PromServer + services.Checker +} + +func newServer(loggerName string) (*Server, error) { + s := &Server{ // default prometheus.Registerer GRPCOpts: loop.SetupTelemetry(nil), } lggr, err := loop.NewLogger() if err != nil { - fmt.Fprintf(os.Stderr, "Failed to create logger: %s\n", err) - os.Exit(1) + return nil, fmt.Errorf("error creating logger: %s", err) } lggr = logger.Named(lggr, loggerName) s.Logger = logger.Sugared(lggr) + return s, nil +} +func (s *Server) start() error { envCfg, err := GetEnvConfig() if err != nil { - lggr.Fatalf("Failed to get environment configuration: %s\n", err) + return fmt.Errorf("error getting environment configuration: %w", err) } - s.PromServer = NewPromServer(envCfg.PrometheusPort(), lggr) + s.PromServer = NewPromServer(envCfg.PrometheusPort(), s.Logger) err = s.PromServer.Start() if err != nil { - lggr.Fatalf("Unrecoverable error starting prometheus server: %s", err) + return fmt.Errorf("error starting prometheus server: %w", err) } s.Checker = services.NewChecker() err = s.Checker.Start() if err != nil { - lggr.Fatalf("Failed to start health checker: %v", err) + return fmt.Errorf("error starting health checker: %w", err) } - return &s -} - -// Server holds common plugin server fields. -type Server struct { - loop.GRPCOpts - Logger logger.SugaredLogger - *PromServer - services.Checker + return nil } // MustRegister registers the Checkable with services.Checker, or exits upon failure. @@ -62,7 +93,7 @@ func (s *Server) MustRegister(c services.Checkable) { // Stop closes resources and flushes logs. func (s *Server) Stop() { s.Logger.ErrorIfFn(s.Checker.Close, "Failed to close health checker") - s.Logger.ErrorIfFn(s.PromServer.Close, "error closing prometheus server") + s.Logger.ErrorIfFn(s.PromServer.Close, "Failed to close prometheus server") if err := s.Logger.Sync(); err != nil { fmt.Println("Failed to sync logger:", err) } diff --git a/sonar-project.properties b/sonar-project.properties index fbe1ad9d0a..8b442fc8ba 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -5,7 +5,7 @@ sonar.python.version=3.8 # Full exclusions from the static analysis sonar.exclusions=**/node_modules/**/*,**/mocks/**/*, **/testdata/**/*, **/contracts/typechain/**/*, **/contracts/artifacts/**/*, **/contracts/cache/**/*, **/contracts/scripts/**/*, **/generated/**/*, **/fixtures/**/*, **/docs/**/*, **/tools/**/*, **/*.pb.go, **/*report.xml, **/*.config.ts, **/*.txt, **/*.abi, **/*.bin, **/*_codecgen.go # Coverage exclusions -sonar.coverage.exclusions=**/*.test.ts, **/*_test.go, **/contracts/test/**/*, **/contracts/**/tests/**/*, **/core/**/testutils/**/*, **/core/**/mocks/**/*, **/core/**/cltest/**/*, **/integration-tests/**/*, **/generated/**/*, **/core/scripts**/* , **/*.pb.go, ./plugins/**/*, **/main.go +sonar.coverage.exclusions=**/*.test.ts, **/*_test.go, **/contracts/test/**/*, **/contracts/**/tests/**/*, **/core/**/testutils/**/*, **/core/**/mocks/**/*, **/core/**/cltest/**/*, **/integration-tests/**/*, **/generated/**/*, **/core/scripts**/* , **/*.pb.go, ./plugins/**/*, **/main.go, **/0195_add_not_null_to_evm_chain_id_in_job_specs.go # Duplication exclusions sonar.cpd.exclusions=**/contracts/**/*.sol, **/config.go, /core/services/ocr2/plugins/ocr2keeper/evm*/* diff --git a/tools/docker/README.md b/tools/docker/README.md index cd2b39307f..58c1e19669 100644 --- a/tools/docker/README.md +++ b/tools/docker/README.md @@ -25,7 +25,6 @@ Acceptance can be accomplished by using the `acceptance` command. ./compose acceptance ``` -- The explorer can be reached at `http://localhost:8080` - The chainlink node can be reached at `http://localhost:6688` Credentials for logging into the operator-ui can be found [here](../../tools/secrets/apicredentials) @@ -35,7 +34,7 @@ Credentials for logging into the operator-ui can be found [here](../../tools/sec ### Doing local development on the core node Doing quick, iterative changes on the core codebase can still be achieved within the compose setup with the `cld` or `cldo` commands. -The `cld` command will bring up the services that a chainlink node needs to connect to (explorer, parity/geth, postgres), and then attach the users terminal to a docker container containing the host's chainlink repository bind-mounted inside the container at `/usr/local/src/chainlink`. What this means is that any changes made within the host's repository will be synchronized to the container, and vice versa for changes made within the container at `/usr/local/src/chainlink`. +The `cld` command will bring up the services that a chainlink node needs to connect to (parity/geth, postgres), and then attach the users terminal to a docker container containing the host's chainlink repository bind-mounted inside the container at `/usr/local/src/chainlink`. What this means is that any changes made within the host's repository will be synchronized to the container, and vice versa for changes made within the container at `/usr/local/src/chainlink`. This enables a user to make quick changes on either the container or the host, run `cldev` within the attached container, check the new behaviour of the re-built node, and repeat this process until the desired results are achieved. @@ -151,7 +150,7 @@ echo "ALLOW_ORIGINS=http://localhost:1337" > chainlink-variables.env The `logs` command will allow you to follow the logs of any running service. For example: ```bash -./compose up node # starts the node service and all it's dependencies, including devnet, explorer, the DB... +./compose up node # starts the node service and all it's dependencies, including devnet, the DB... ./compose logs devnet # shows the blockchain logs # ^C to exit ./compose logs # shows the combined logs of all running services @@ -217,7 +216,7 @@ The docker env contains direnv, so whatever changes you make locally to your (bi docker build ./tools/docker/ -t chainlink-develop:latest -f ./tools/docker/develop.Dockerfile # create the image docker container create -v /home/ryan/chainlink/chainlink:/root/chainlink --name chainlink-dev chainlink-develop:latest -# if you want to access the db, chain, node, or explorer from the host... expose the relevant ports +# if you want to access the db, chain, node, or from the host... expose the relevant ports # This could also be used in case you want to run some services in the container, and others directly # on the host docker container create -v /home/ryan/chainlink/chainlink:/root/chainlink --name chainlink-dev -p 5432:5432 -p 6688:6688 -p 6689:6689 -p 3000:3000 -p 3001:3001 -p 8545:8545 -p 8546:8546 chainlink-develop:latest diff --git a/tools/docker/cldev.Dockerfile b/tools/docker/cldev.Dockerfile index 0257a766b6..72f2f06d7c 100644 --- a/tools/docker/cldev.Dockerfile +++ b/tools/docker/cldev.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.17-buster +FROM golang:1.21-bullseye ARG SRCROOT=/usr/local/src/chainlink WORKDIR ${SRCROOT} diff --git a/tools/docker/compose b/tools/docker/compose index b8150e2c89..b16c1e1933 100755 --- a/tools/docker/compose +++ b/tools/docker/compose @@ -4,11 +4,6 @@ set -ex export DOCKER_BUILDKIT=1 export COMPOSE_DOCKER_CLI_BUILD=1 -# Export Explorer docker tag to be used in docker-compose files -if [ -z $EXPLORER_DOCKER_TAG ]; then - export EXPLORER_DOCKER_TAG="develop" -fi - base_files="-f docker-compose.yaml -f docker-compose.postgres.yaml" # Allow for choosing between geth or parity if [ $GETH_MODE ]; then @@ -17,13 +12,6 @@ else base_files="$base_files -f docker-compose.paritynet.yaml" fi -# Build Explorer from source if path is set -if [ $EXPLORER_SOURCE_PATH ]; then - base_files="$base_files -f docker-compose.explorer-source.yaml" -else - base_files="$base_files -f docker-compose.explorer.yaml" -fi - base="docker-compose $base_files" # base config, used standalone for acceptance dev="$base -f docker-compose.dev.yaml" # config for cldev diff --git a/tools/docker/dev-secrets.toml b/tools/docker/dev-secrets.toml index 41554f9c4f..b27b8a8a8e 100644 --- a/tools/docker/dev-secrets.toml +++ b/tools/docker/dev-secrets.toml @@ -2,7 +2,3 @@ [Database] AllowSimplePasswords = true - -[Explorer] -AccessKey = 'u4HULe0pj5xPyuvv' -Secret = 'YDxkVRTmcliehGZPw7f0L2Td3sz3LqutAQyy7sLCEIP6xcWzbO8zgfBWi4DXC6U6' diff --git a/tools/docker/develop.Dockerfile b/tools/docker/develop.Dockerfile index 9ebf82df07..46fad445d6 100644 --- a/tools/docker/develop.Dockerfile +++ b/tools/docker/develop.Dockerfile @@ -29,8 +29,6 @@ RUN echo "listen_addresses='*'" >> /etc/postgresql/10/main/postgresql.conf RUN /etc/init.d/postgresql start &&\ createdb chainlink_test &&\ createdb node_dev &&\ - createdb explorer_dev &&\ - createdb explorer_test &&\ createuser --superuser --no-password root &&\ psql -c "ALTER USER postgres PASSWORD 'node';" diff --git a/tools/docker/docker-compose.explorer-source.yaml b/tools/docker/docker-compose.explorer-source.yaml deleted file mode 100644 index 25793e7cfe..0000000000 --- a/tools/docker/docker-compose.explorer-source.yaml +++ /dev/null @@ -1,19 +0,0 @@ -version: '3.5' - -services: - explorer: - container_name: chainlink-explorer - image: chainlink/explorer - build: - context: $EXPLORER_SOURCE_PATH - dockerfile: explorer/Dockerfile - entrypoint: yarn workspace @chainlink/explorer dev:compose - restart: always - ports: - - 3001 - depends_on: - - explorer-db - environment: - - EXPLORER_COOKIE_SECRET - - EXPLORER_SERVER_PORT - - PGPASSWORD=$EXPLORER_PGPASSWORD diff --git a/tools/docker/docker-compose.explorer.yaml b/tools/docker/docker-compose.explorer.yaml deleted file mode 100644 index 85361e1522..0000000000 --- a/tools/docker/docker-compose.explorer.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: '3.5' - -services: - explorer: - container_name: chainlink-explorer - image: smartcontract/explorer:${EXPLORER_DOCKER_TAG} - entrypoint: yarn workspace @chainlink/explorer dev:compose - restart: always - ports: - - 3001 - depends_on: - - explorer-db - environment: - - EXPLORER_COOKIE_SECRET - - EXPLORER_SERVER_PORT - - PGPASSWORD=$EXPLORER_PGPASSWORD diff --git a/tools/docker/docker-compose.yaml b/tools/docker/docker-compose.yaml index 19f8026b20..4d3ef7def2 100644 --- a/tools/docker/docker-compose.yaml +++ b/tools/docker/docker-compose.yaml @@ -24,8 +24,6 @@ services: - keystore - config - secrets - depends_on: - - explorer node-2: container_name: chainlink-node-2 @@ -48,20 +46,9 @@ services: - config - secrets - explorer-db: - container_name: chainlink-explorer-db - image: postgres:11.6 - volumes: - - explorer-db-data:/var/lib/postgresql/data - ports: - - 5433:5432 - environment: - POSTGRES_DB: $EXPLORER_DB_NAME - POSTGRES_PASSWORD: $EXPLORER_PGPASSWORD - # TODO # - replace clroot with secrets -# - extract explorer and tools into separate docker-compose files +# - extract tools into separate docker-compose files secrets: node_password: @@ -75,5 +62,3 @@ secrets: secrets: file: dev-secrets.toml -volumes: - explorer-db-data: diff --git a/tools/flakeytests/reporter.go b/tools/flakeytests/reporter.go index 04dad6fea0..beecd8b3e4 100644 --- a/tools/flakeytests/reporter.go +++ b/tools/flakeytests/reporter.go @@ -45,12 +45,12 @@ type LokiReporter struct { ctx Context } -func (l *LokiReporter) createRequest(flakeyTests map[string][]string) (pushRequest, error) { +func (l *LokiReporter) createRequest(flakeyTests map[string]map[string]struct{}) (pushRequest, error) { vs := [][]string{} now := l.now() nows := fmt.Sprintf("%d", now.UnixNano()) for pkg, tests := range flakeyTests { - for _, t := range tests { + for t := range tests { d, err := json.Marshal(flakeyTest{ Package: pkg, TestName: t, @@ -117,7 +117,7 @@ func (l *LokiReporter) makeRequest(pushReq pushRequest) error { return err } -func (l *LokiReporter) Report(flakeyTests map[string][]string) error { +func (l *LokiReporter) Report(flakeyTests map[string]map[string]struct{}) error { pushReq, err := l.createRequest(flakeyTests) if err != nil { return err diff --git a/tools/flakeytests/reporter_test.go b/tools/flakeytests/reporter_test.go index 325c39a043..f63b89273c 100644 --- a/tools/flakeytests/reporter_test.go +++ b/tools/flakeytests/reporter_test.go @@ -12,15 +12,17 @@ import ( func TestMakeRequest_SingleTest(t *testing.T) { now := time.Now() ts := fmt.Sprintf("%d", now.UnixNano()) - ft := map[string][]string{ - "core/assets": {"TestLink"}, + ft := map[string]map[string]struct{}{ + "core/assets": map[string]struct{}{ + "TestLink": struct{}{}, + }, } lr := &LokiReporter{auth: "bla", host: "bla", command: "go_core_tests", now: func() time.Time { return now }} pr, err := lr.createRequest(ft) require.NoError(t, err) assert.Len(t, pr.Streams, 1) assert.Equal(t, pr.Streams[0].Stream, map[string]string{"command": "go_core_tests", "app": "flakey-test-reporter"}) - assert.Equal(t, pr.Streams[0].Values, [][]string{ + assert.ElementsMatch(t, pr.Streams[0].Values, [][]string{ {ts, "{\"package\":\"core/assets\",\"test_name\":\"TestLink\",\"fq_test_name\":\"core/assets:TestLink\"}"}, {ts, "{\"num_flakes\":1}"}, }) @@ -29,8 +31,11 @@ func TestMakeRequest_SingleTest(t *testing.T) { func TestMakeRequest_MultipleTests(t *testing.T) { now := time.Now() ts := fmt.Sprintf("%d", now.UnixNano()) - ft := map[string][]string{ - "core/assets": {"TestLink", "TestCore"}, + ft := map[string]map[string]struct{}{ + "core/assets": map[string]struct{}{ + "TestLink": struct{}{}, + "TestCore": struct{}{}, + }, } lr := &LokiReporter{auth: "bla", host: "bla", command: "go_core_tests", now: func() time.Time { return now }} pr, err := lr.createRequest(ft) @@ -38,7 +43,7 @@ func TestMakeRequest_MultipleTests(t *testing.T) { assert.Len(t, pr.Streams, 1) assert.Equal(t, pr.Streams[0].Stream, map[string]string{"command": "go_core_tests", "app": "flakey-test-reporter"}) - assert.Equal(t, pr.Streams[0].Values, [][]string{ + assert.ElementsMatch(t, pr.Streams[0].Values, [][]string{ {ts, "{\"package\":\"core/assets\",\"test_name\":\"TestLink\",\"fq_test_name\":\"core/assets:TestLink\"}"}, {ts, "{\"package\":\"core/assets\",\"test_name\":\"TestCore\",\"fq_test_name\":\"core/assets:TestCore\"}"}, {ts, "{\"num_flakes\":2}"}, @@ -48,13 +53,13 @@ func TestMakeRequest_MultipleTests(t *testing.T) { func TestMakeRequest_NoTests(t *testing.T) { now := time.Now() ts := fmt.Sprintf("%d", now.UnixNano()) - ft := map[string][]string{} + ft := map[string]map[string]struct{}{} lr := &LokiReporter{auth: "bla", host: "bla", command: "go_core_tests", now: func() time.Time { return now }} pr, err := lr.createRequest(ft) require.NoError(t, err) assert.Len(t, pr.Streams, 1) assert.Equal(t, pr.Streams[0].Stream, map[string]string{"command": "go_core_tests", "app": "flakey-test-reporter"}) - assert.Equal(t, pr.Streams[0].Values, [][]string{ + assert.ElementsMatch(t, pr.Streams[0].Values, [][]string{ {ts, "{\"num_flakes\":0}"}, }) } @@ -62,13 +67,13 @@ func TestMakeRequest_NoTests(t *testing.T) { func TestMakeRequest_WithContext(t *testing.T) { now := time.Now() ts := fmt.Sprintf("%d", now.UnixNano()) - ft := map[string][]string{} + ft := map[string]map[string]struct{}{} lr := &LokiReporter{auth: "bla", host: "bla", command: "go_core_tests", now: func() time.Time { return now }, ctx: Context{CommitSHA: "42"}} pr, err := lr.createRequest(ft) require.NoError(t, err) assert.Len(t, pr.Streams, 1) assert.Equal(t, pr.Streams[0].Stream, map[string]string{"command": "go_core_tests", "app": "flakey-test-reporter"}) - assert.Equal(t, pr.Streams[0].Values, [][]string{ + assert.ElementsMatch(t, pr.Streams[0].Values, [][]string{ {ts, "{\"num_flakes\":0,\"commit_sha\":\"42\"}"}, }) } diff --git a/tools/flakeytests/runner.go b/tools/flakeytests/runner.go index ab8f2c6222..d935000222 100644 --- a/tools/flakeytests/runner.go +++ b/tools/flakeytests/runner.go @@ -20,37 +20,52 @@ var ( ) type Runner struct { - readers []io.Reader - numReruns int - runTestFn runTestCmd - parse parseFn - reporter reporter + readers []io.Reader + testCommand tester + numReruns int + parse parseFn + reporter reporter +} + +type tester interface { + test(pkg string, tests []string, w io.Writer) error } type reporter interface { - Report(map[string][]string) error + Report(map[string]map[string]struct{}) error } -type runTestCmd func(pkg string, testNames []string, numReruns int, w io.Writer) error type parseFn func(readers ...io.Reader) (map[string]map[string]int, error) func NewRunner(readers []io.Reader, reporter reporter, numReruns int) *Runner { + tc := &testCommand{ + repo: "github.com/smartcontractkit/chainlink/v2", + command: "./tools/bin/go_core_tests", + overrides: func(*exec.Cmd) {}, + } return &Runner{ - readers: readers, - numReruns: numReruns, - runTestFn: runGoTest, - parse: parseOutput, - reporter: reporter, + readers: readers, + numReruns: numReruns, + testCommand: tc, + parse: parseOutput, + reporter: reporter, } } -func runGoTest(pkg string, tests []string, numReruns int, w io.Writer) error { - pkg = strings.Replace(pkg, "github.com/smartcontractkit/chainlink/v2", "", -1) +type testCommand struct { + command string + repo string + overrides func(*exec.Cmd) +} + +func (t *testCommand) test(pkg string, tests []string, w io.Writer) error { + replacedPkg := strings.Replace(pkg, t.repo, "", -1) testFilter := strings.Join(tests, "|") - cmd := exec.Command("./tools/bin/go_core_tests", fmt.Sprintf(".%s", pkg)) //#nosec - cmd.Env = append(os.Environ(), fmt.Sprintf("TEST_FLAGS=-count %d -run %s", numReruns, testFilter)) + cmd := exec.Command(t.command, fmt.Sprintf(".%s", replacedPkg)) //#nosec + cmd.Env = append(os.Environ(), fmt.Sprintf("TEST_FLAGS=-run %s", testFilter)) cmd.Stdout = io.MultiWriter(os.Stdout, w) cmd.Stderr = io.MultiWriter(os.Stderr, w) + t.overrides(cmd) return cmd.Run() } @@ -123,8 +138,9 @@ type exitCoder interface { ExitCode() int } -func (r *Runner) runTests(failedTests map[string]map[string]int) (io.Reader, error) { - var out bytes.Buffer +func (r *Runner) runTests(failedTests map[string]map[string]int) (map[string]map[string]struct{}, error) { + suspectedFlakes := map[string]map[string]struct{}{} + for pkg, tests := range failedTests { ts := []string{} for test := range tests { @@ -132,21 +148,40 @@ func (r *Runner) runTests(failedTests map[string]map[string]int) (io.Reader, err } log.Printf("Executing test command with parameters: pkg=%s, tests=%+v, numReruns=%d\n", pkg, ts, r.numReruns) - err := r.runTestFn(pkg, ts, r.numReruns, &out) - if err != nil { - log.Printf("Test command errored: %s\n", err) - // There was an error because the command failed with a non-zero - // exit code. This could just mean that the test failed again, so let's - // keep going. - var exErr exitCoder - if errors.As(err, &exErr) && exErr.ExitCode() > 0 { - continue + for i := 0; i < r.numReruns; i++ { + var out bytes.Buffer + + err := r.testCommand.test(pkg, ts, &out) + if err != nil { + log.Printf("Test command errored: %s\n", err) + // There was an error because the command failed with a non-zero + // exit code. This could just mean that the test failed again, so let's + // keep going. + var exErr exitCoder + if errors.As(err, &exErr) && exErr.ExitCode() > 0 { + continue + } + return suspectedFlakes, err + } + + fr, err := r.parse(&out) + if err != nil { + return nil, err + } + + for t := range tests { + failures := fr[pkg][t] + if failures == 0 { + if suspectedFlakes[pkg] == nil { + suspectedFlakes[pkg] = map[string]struct{}{} + } + suspectedFlakes[pkg][t] = struct{}{} + } } - return &out, err } } - return &out, nil + return suspectedFlakes, nil } func (r *Runner) Run() error { @@ -155,28 +190,11 @@ func (r *Runner) Run() error { return err } - output, err := r.runTests(failedTests) + suspectedFlakes, err := r.runTests(failedTests) if err != nil { return err } - failedReruns, err := r.parse(output) - if err != nil { - return err - } - - suspectedFlakes := map[string][]string{} - // A test is flakey if it appeared in the list of original flakey tests - // and doesn't appear in the reruns, or if it hasn't failed each additional - // run, i.e. if it hasn't twice after being re-run. - for pkg, t := range failedTests { - for test := range t { - if failedReruns[pkg][test] != r.numReruns { - suspectedFlakes[pkg] = append(suspectedFlakes[pkg], test) - } - } - } - if len(suspectedFlakes) > 0 { log.Printf("ERROR: Suspected flakes found: %+v\n", suspectedFlakes) } else { diff --git a/tools/flakeytests/runner_test.go b/tools/flakeytests/runner_test.go index 7def5092b0..8fa81db5ba 100644 --- a/tools/flakeytests/runner_test.go +++ b/tools/flakeytests/runner_test.go @@ -2,6 +2,8 @@ package flakeytests import ( "io" + "os" + "os/exec" "strings" "testing" @@ -10,16 +12,16 @@ import ( ) type mockReporter struct { - entries map[string][]string + entries map[string]map[string]struct{} } -func (m *mockReporter) Report(entries map[string][]string) error { +func (m *mockReporter) Report(entries map[string]map[string]struct{}) error { m.entries = entries return nil } func newMockReporter() *mockReporter { - return &mockReporter{entries: map[string][]string{}} + return &mockReporter{entries: map[string]map[string]struct{}{}} } func TestParser(t *testing.T) { @@ -86,16 +88,29 @@ func TestParser_SuccessfulOutput(t *testing.T) { assert.Len(t, ts, 0) } +type testAdapter func(string, []string, io.Writer) error + +func (t testAdapter) test(pkg string, tests []string, out io.Writer) error { + return t(pkg, tests, out) +} + func TestRunner_WithFlake(t *testing.T) { - output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}` + initialOutput := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}` + outputs := []string{ + `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}`, + ``, + } m := newMockReporter() + i := 0 r := &Runner{ numReruns: 2, - readers: []io.Reader{strings.NewReader(output)}, - runTestFn: func(pkg string, testNames []string, numReruns int, w io.Writer) error { - _, err := w.Write([]byte(output)) + readers: []io.Reader{strings.NewReader(initialOutput)}, + + testCommand: testAdapter(func(pkg string, testNames []string, w io.Writer) error { + _, err := w.Write([]byte(outputs[i])) + i++ return err - }, + }), parse: parseOutput, reporter: m, } @@ -105,22 +120,32 @@ func TestRunner_WithFlake(t *testing.T) { err := r.Run() require.NoError(t, err) assert.Len(t, m.entries, 1) - assert.Equal(t, m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"], []string{"TestLink"}) + _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestLink"] + assert.True(t, ok) } func TestRunner_WithFailedPackage(t *testing.T) { - output := ` + initialOutput := ` {"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} {"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Elapsed":0} ` + outputs := []string{` +{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} +{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Elapsed":0} +`, + ``, + } + m := newMockReporter() + i := 0 r := &Runner{ numReruns: 2, - readers: []io.Reader{strings.NewReader(output)}, - runTestFn: func(pkg string, testNames []string, numReruns int, w io.Writer) error { - _, err := w.Write([]byte(output)) + readers: []io.Reader{strings.NewReader(initialOutput)}, + testCommand: testAdapter(func(pkg string, testNames []string, w io.Writer) error { + _, err := w.Write([]byte(outputs[i])) + i++ return err - }, + }), parse: parseOutput, reporter: m, } @@ -130,7 +155,8 @@ func TestRunner_WithFailedPackage(t *testing.T) { err := r.Run() require.NoError(t, err) assert.Len(t, m.entries, 1) - assert.Equal(t, m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"], []string{"TestLink"}) + _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestLink"] + assert.True(t, ok) } func TestRunner_AllFailures(t *testing.T) { @@ -144,10 +170,10 @@ func TestRunner_AllFailures(t *testing.T) { r := &Runner{ numReruns: 2, readers: []io.Reader{strings.NewReader(output)}, - runTestFn: func(pkg string, testNames []string, numReruns int, w io.Writer) error { + testCommand: testAdapter(func(pkg string, testNames []string, w io.Writer) error { _, err := w.Write([]byte(rerunOutput)) return err - }, + }), parse: parseOutput, reporter: m, } @@ -160,25 +186,28 @@ func TestRunner_AllFailures(t *testing.T) { func TestRunner_RerunSuccessful(t *testing.T) { output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}` - rerunOutput := ` -{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} -{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} -` + rerunOutputs := []string{ + `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}`, + `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}`, + } m := newMockReporter() + i := 0 r := &Runner{ numReruns: 2, readers: []io.Reader{strings.NewReader(output)}, - runTestFn: func(pkg string, testNames []string, numReruns int, w io.Writer) error { - _, err := w.Write([]byte(rerunOutput)) + testCommand: testAdapter(func(pkg string, testNames []string, w io.Writer) error { + _, err := w.Write([]byte(rerunOutputs[i])) + i++ return err - }, + }), parse: parseOutput, reporter: m, } err := r.Run() require.NoError(t, err) - assert.Equal(t, m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"], []string{"TestLink"}) + _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestLink"] + assert.True(t, ok) } func TestRunner_RootLevelTest(t *testing.T) { @@ -189,17 +218,18 @@ func TestRunner_RootLevelTest(t *testing.T) { r := &Runner{ numReruns: 2, readers: []io.Reader{strings.NewReader(output)}, - runTestFn: func(pkg string, testNames []string, numReruns int, w io.Writer) error { + testCommand: testAdapter(func(pkg string, testNames []string, w io.Writer) error { _, err := w.Write([]byte(rerunOutput)) return err - }, + }), parse: parseOutput, reporter: m, } err := r.Run() require.NoError(t, err) - assert.Equal(t, m.entries["github.com/smartcontractkit/chainlink/v2/"], []string{"TestConfigDocs"}) + _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/"]["TestConfigDocs"] + assert.True(t, ok) } type exitError struct{} @@ -211,25 +241,28 @@ func (e *exitError) Error() string { return "exit code: 1" } func TestRunner_RerunFailsWithNonzeroExitCode(t *testing.T) { output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}` - rerunOutput := ` -{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} -{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} -` + rerunOutputs := []string{ + `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}`, + `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}`, + } m := newMockReporter() + i := 0 r := &Runner{ numReruns: 2, readers: []io.Reader{strings.NewReader(output)}, - runTestFn: func(pkg string, testNames []string, numReruns int, w io.Writer) error { - _, _ = w.Write([]byte(rerunOutput)) - return &exitError{} - }, + testCommand: testAdapter(func(pkg string, testNames []string, w io.Writer) error { + _, err := w.Write([]byte(rerunOutputs[i])) + i++ + return err + }), parse: parseOutput, reporter: m, } err := r.Run() require.NoError(t, err) - assert.Equal(t, m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"], []string{"TestLink"}) + _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestLink"] + assert.True(t, ok) } func TestRunner_RerunWithNonZeroExitCodeDoesntStopCommand(t *testing.T) { @@ -243,14 +276,10 @@ func TestRunner_RerunWithNonZeroExitCodeDoesntStopCommand(t *testing.T) { } rerunOutputs := []string{ - ` -{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} -{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0} -`, - ` -{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2","Test":"TestMaybeReservedLinkV2","Elapsed":0} -{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2","Test":"TestMaybeReservedLinkV2","Elapsed":0} -`, + `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}`, + `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"pass","Package":"github.com/smartcontractkit/chainlink/v2/core/assets","Test":"TestLink","Elapsed":0}`, + `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2","Test":"TestMaybeReservedLinkV2","Elapsed":0}`, + `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/core/services/vrf/v2","Test":"TestMaybeReservedLinkV2","Elapsed":0}`, } index := 0 @@ -258,12 +287,11 @@ func TestRunner_RerunWithNonZeroExitCodeDoesntStopCommand(t *testing.T) { r := &Runner{ numReruns: 2, readers: outputs, - runTestFn: func(pkg string, testNames []string, numReruns int, w io.Writer) error { - - _, _ = w.Write([]byte(rerunOutputs[index])) + testCommand: testAdapter(func(pkg string, testNames []string, w io.Writer) error { + _, err := w.Write([]byte(rerunOutputs[index])) index++ - return &exitError{} - }, + return err + }), parse: parseOutput, reporter: m, } @@ -271,6 +299,82 @@ func TestRunner_RerunWithNonZeroExitCodeDoesntStopCommand(t *testing.T) { err := r.Run() require.NoError(t, err) calls := index - assert.Equal(t, 2, calls) - assert.Equal(t, m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"], []string{"TestLink"}) + assert.Equal(t, 4, calls) + + _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/core/assets"]["TestLink"] + assert.True(t, ok) +} + +// Used for integration tests +func TestSkippedForTests(t *testing.T) { + if os.Getenv("FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST") != "1" { + t.Skip() + } + + go func() { + panic("skipped test") + }() +} + +// Used for integration tests +func TestSkippedForTests_Success(t *testing.T) { + if os.Getenv("FLAKEY_TEST_RUNNER_RUN_FIXTURE_TEST") != "1" { + t.Skip() + } + + assert.True(t, true) +} + +func TestParsesPanicCorrectly(t *testing.T) { + output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/tools/flakeytests/","Test":"TestSkippedForTests","Elapsed":0}` + + m := newMockReporter() + tc := &testCommand{ + repo: "github.com/smartcontractkit/chainlink/v2/tools/flakeytests", + command: "../bin/go_core_tests", + overrides: func(cmd *exec.Cmd) { + cmd.Env = append(cmd.Env, "FLAKEY_TESTRUNNER_RUN_FIXTURE_TEST=1") + cmd.Stdout = io.Discard + cmd.Stderr = io.Discard + }, + } + r := &Runner{ + numReruns: 2, + readers: []io.Reader{strings.NewReader(output)}, + testCommand: tc, + parse: parseOutput, + reporter: m, + } + + err := r.Run() + require.NoError(t, err) + _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/tools/flakeytests"]["TestSkippedForTests"] + assert.False(t, ok) +} + +func TestIntegration(t *testing.T) { + output := `{"Time":"2023-09-07T15:39:46.378315+01:00","Action":"fail","Package":"github.com/smartcontractkit/chainlink/v2/tools/flakeytests/","Test":"TestSkippedForTests_Success","Elapsed":0}` + + m := newMockReporter() + tc := &testCommand{ + repo: "github.com/smartcontractkit/chainlink/v2/tools/flakeytests", + command: "../bin/go_core_tests", + overrides: func(cmd *exec.Cmd) { + cmd.Env = append(cmd.Env, "FLAKEY_TESTRUNNER_RUN_FIXTURE_TEST=1") + cmd.Stdout = io.Discard + cmd.Stderr = io.Discard + }, + } + r := &Runner{ + numReruns: 2, + readers: []io.Reader{strings.NewReader(output)}, + testCommand: tc, + parse: parseOutput, + reporter: m, + } + + err := r.Run() + require.NoError(t, err) + _, ok := m.entries["github.com/smartcontractkit/chainlink/v2/tools/flakeytests"]["TestSkippedForTests_Success"] + assert.False(t, ok) }